🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 1. this关键字 JavaScript中的this指向问题,有时候会让人难以捉摸,随着学习的深入,我们可以逐渐了解,函数内部的this有如下几个特点: 1. 函数在定义的时候this是不确定的,只有在调用的时候才可以确定 2. 一般函数直接执行,内部this指向全局window 3. 函数作为一个对象的方法,被该对象所调用,那么this指向的是该对象 4. 构造函数中的this其实是一个隐式对象,类似一个初始化的模型,所有方法和属性都挂载到了这个隐式对象身上,后续通过new关键字来调用,从而实现实例化 | 调用方式 | 非严格模式 | 备注 | | --- | --- | --- | | 普通函数调用 | window | 严格模式下是 undefined | | 构造函数调用 | 实例对象 | 原型方法中 this 也是实例对象 | | 对象方法调用 | 该方法所属对象 | 紧挨着的对象 | | 事件绑定方法 | 绑定事件对象 | | | 定时器函数 | window | # 2. call、apply、bind函数 call、apply、bind函数可以将`this`指向规定的对象。 <mark>1. call函数</mark> 语法: ```js fun.call(thisArg[, arg1[, arg2[, ...]]]) //[ ] 表示可选, fun为函数 ``` 注意:该方法的作用和 apply() 方法类似,只有一个区别,就是 call() 方法接受的是若干个参数的列表,而 apply() 方法接受的是一个包含多个参数的数组。 - `thisArg` + 在 fun 函数运行时指定的 this 值 + 如果指定了 null 或者 undefined 则内部 this 指向 window + 值为原始值(数字,字符串,布尔值)的`this`会指向该原始值的自动包装对象。 - `arg1, arg2, ...` * 指定的参数列表 * 返回值 * 返回值是你调用的方法的返回值,若该方法没有返回值,则返回`undefined` ```js function fun1(x, y) { console.log(x+y); } var message = { name: "李明", age: 24 } // call函数调用了fun1函数 // fun1的this指向了message对象 // 100,200两个实参对应fun1的两个形参 fun1.call(message, 100, 200); // 300 ``` <mark>2. apply函数</mark> 语法: ```js fun.apply(thisArg, [argsArray]) ``` `apply()` 与 `call()` 非常相似,不同之处在于提供参数的方式。`apply()` 使用参数数组而不是一组参数列表。例如: ```js fun.apply(this, ['eat', 'bananas']) ``` <mark>3. bind函数</mark> bind() 函数会创建一个新函数(称为绑定函数),新函数与被调函数具有相同的函数体(在 ECMAScript 5 规范中内置的call属性)。 当 ```fun.bind(thisArg,..)时,``` ```fun的this``` 绑定到 bind() 的第一个参数,该参数不能被重写。绑定函数被调用时,bind() 也接受预设的参数提供给原函数,即```fun```。 一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的 ```this``` 值被忽略,同时调用时的参数被提供. ```js function f1(x, y) { console.log(x+y); } var obj = { age: 10, getAge: function() { console.log(this.age); } } // f1的this指向了obj // 100,200两个实参对应f1中的两个形参 // bind函数返回了ff函数,结构与f1一样 // bind函数并没有调用f1函数,所以f1.bind不会执行f1的代码 var ff = f1.bind(obj, 100, 200); // ff就是绑定函数 ff(); // 300 调用ff时上面的那两个实参100,200也提供给了ff ``` 语法: ```js fun.bind(thisArg[, arg1[, arg2[, ...]]]) ``` - thisArg + 当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用new 操作符调用绑定函数时,该参数无效。 - arg1, arg2, ... + 当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。 返回值:返回由指定的this值和初始化参数改造的原函数拷贝。 实例1: ```js this.x = 9; var module = { x: 81, getX: function() { return this.x; } }; module.getX(); // 返回 81 var retrieveX = module.getX; retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域 // 创建一个新函数,将"this"绑定到module对象 // 新手可能会被全局的x变量和module里的属性x所迷惑 var boundGetX = retrieveX.bind(module); boundGetX(); // 返回 81 ``` 实例2: ```js function LateBloomer() { this.petalCount = Math.ceil(Math.random() * 12) + 1; } // Declare bloom after a delay of 1 second LateBloomer.prototype.bloom = function() { window.setTimeout(this.declare.bind(this), 1000); }; LateBloomer.prototype.declare = function() { console.log('I am a beautiful flower with ' + this.petalCount + ' petals!'); }; var flower = new LateBloomer(); flower.bloom(); // 一秒钟后, 调用'declare'方法 ```