函数中的 this 不止有 72 变
时间:2025-11-04 08:19:27 出处:域名阅读(143)
在课程 连接你、函数我、不止他 —— this 中我们学习了 this,有变最后留了一个问题,函数如何修改 this 的不止指向,今天一起学习。有变
修改 this 的函数指向可通过 apply、call、不止bind 这三个函数中的有变任意一个实现。那这三个函数是函数谁的方法呢?
在 MDN 中我查到了:

这张图说明了这 3 个函数是 Function prototype 的方法,也就是不止说「每个函数都有着三个方法」。当定义一个函数,有变这个函数默认包含这三个方法。函数
我们感受一下 Vue.js 中关于 apply、不止call 和 bind 的有变使用:
apply 的应用:
function once (fn) { var called = false; return function () { if (!called) { called = true; fn.apply(this, arguments); } } }call 的应用:
var hasOwnProperty = Object.prototype.hasOwnProperty; function hasOwn (obj, key) { return hasOwnProperty.call(obj, key) }bind的应用:
function polyfillBind (fn, ctx) { function boundFn (a) { var l = arguments.length; return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx) } boundFn._length = fn.length; return boundFn } function nativeBind (fn, ctx) { return fn.bind(ctx) } var bind = Function.prototype.bind ? nativeBind : polyfillBind;你可能看不懂上面的用法,下面我们一一抛开谜底。
当一个新事物的出现,总是云服务器有目的的,那么 apply、call 和 bind 的出现是为了解决什么问题呢?它们为什么是函数的方法呢?为什么不是其它对象的方法。
通过 apply、call 可以自定义 this 调用某个函数,比如定义一个全局函数(严格模式):
use strict; function gFun(name, age) { console.log(this); }这个函数可以通过下面 5 种方式调用,也就是说通过 apply、call、bind 可以调用一个函数 F,其中「函数 F 执行上下文中的 this 可以在调用时指定」:
1.直接调用:
gFun(suyan, 20); // this 为 undefined2.通过 this 调用:
this.gFun(suyan, 20); // this 为 window3.通过 apply 调用,把所有的参数组合成一个数组作为 apply 的参数:
gFun.apply(this, [suyan, 20]); // this 为 window4.通过 call 调用,参数通过逗号分割,这是与 apply 调用的区别:
gFun.call(this, suyan, 20); // this 为 window5.通过 bind 调用,会返回一个原函数的拷贝,并拥有指定的 this和参数:
let bGFun = gFun.bind(this, suyan, 20); bGFun(); // this 为 window我们一起看一些例子:
例1、香港云服务器setTimeOut 的使用:
const time = { second: 1, afterOneSecond() { setTimeout(function () { this.second += 1; console.log(this.second); }, 1000); } }; time.afterOneSecond();上面这段代码执行后,第 6 行代码的打印结果是 NaN,在连接你、我、他 —— this 这节课程中我们有提到过 this 设计的一个弊端是不能继承。其实可以通过 bind 改造一下这个函数:
const time = { second: 1, afterOneSecond() { setTimeout(this.timeInvoke.bind(this), 1000); }, timeInvoke() { this.second += 1; console.log(this.second); } }; time.afterOneSecond();函数 timeInvoke 通过 bind 绑定 this,并返回一个新的函数,执行结果为 2。bind 好像具有「暂存」的功能,把当前的 this 暂存起来。
例 2、函数调用
const person = { name: suyan, age: 20, showName(pre) { return pre + - + this.name; }, update(name, age) { this.name = name; this.age = age; } }; function generateName(fun) { let name = fun(); console.log(showName = , name); } generateName(person.showName);执行上面代码会报错,因为 showName 中的 this 为 undefined:

可以通过 bind 「暂存 this」:
const person = { name: suyan, age: 20, showName(pre) { return pre + - + this.name; }, update(name, age) { this.name = name; this.age = age; } }; function generateName(fun) { let name = fun(); console.log(showName = , name); } // 指定 this 为 person 对象 let bindShowName = person.showName.bind(person, 前端小课); generateName(bindShowName);例 3、构造函数,通过 call 来调用某个函数,替换 this。
function Product(name, price) { this.name = name; this.price = price; } function Food(name, price) { // 调用 Product 函数 Product.call(this, name, price); this.catagory = food; } let food = new Food(包子, 1); console.log(food.name); // 包子例 4、调用匿名函数
const animals = [ { name: King }, { name: Fail } ]; for (let i = 0; i < animals.length; i++) { (function (i) { // 可以直接使用 this this.print = function () { console.log(# + i + + this.name); }; this.print(); }).call(animals[i], i); }结果为:

回头再看看课程开始之前 Vue 中关于 apply、call 和 bind 的应用,是不是企商汇能看懂了?
猜你喜欢
- 体验SkullcandyInkd耳机的音质和舒适度(探索这款耳机的优缺点并提供全面评价)
 - 七彩虹1050(打造绚丽画面,畅享游戏乐趣)
 - 以智购通讯(智能手机、套餐、维修,满足你所有通讯需求)
 - 深入探究Z8700处理器的性能与优势(探索IntelZ8700处理器的技术特点和应用领域)
 - 解决电脑关键事件错误的有效方法(保护您的电脑免受关键事件错误的影响)
 - 美的天翼星空调的优势与特点(舒适静音,智能节能,高效降温,品质保障)
 - 努比亚Z11S(前所未有的设计与功能体验)
 - 评测dostyle平板电脑——性能与使用体验(轻薄便携,畅享高效办公和多媒体娱乐)
 - 飞利浦SHB6250音质的真实评价(揭秘SHB6250的音质表现,解锁你的音乐世界)