JavaScript中的this相关
在JavaScript中,this关键字的表现和其他语言有略微的区别, 在js的严格模式和非严格模式之间也会有一些区别。
this.value = 1;
function test_1(){
console.log(this.value);
}
test_1(); // 会输出1
function test_2() {
"use strict";
console.log(this.value);
}
test_2(); // 会报错,因为在严格模式下,此时this指向undefined
简单总结来说,this在非严格模式下,总是会指向调用该函数的对象,此处是根据js特性,指向全局对象window,在非严格模式下,window可以省略,其实这里的value和两个函数test_1、test_2都是挂载在在window对象下的,在严格模式下,window不能省略,所以会报错,但如果把函数test_2调用改写成下面这样就可以了。
window.test_2(); // 会输出1,此时this就会指向了调用test_2()函数的调用对象window
下面的一些函数方法可以改变this的指向,apply()、call()、bind()
-
apply()
是函数的一个方法,作用是改变函数的调用对象。它接收两个参数,它的第一个参数就表示改变后的调用这个函数的对象,第二个参数是可选的,是个数组(或类似数组对象)。因此,这时this
指的就是这第一个参数,如果第一个参数的值为null
或者undefined
时,则此时this
指向全局对象window
。-
语法
func.apply(thisArg, [argsArray])
-
参数
thisArg
必选的。在
func
函数运行时使用的this
值。请注意,this
可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为null
或undefined
时会自动替换为指向全局对象,原始值会被包装。 -
argsArray
可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给
func
函数。如果该参数的值为null
或undefined
,则表示不需要传入任何参数。从ECMAScript 5
开始可以使用类数组对象。 -
返回值
调用有指定
this
值和参数的函数的结果。
-
-
call()
方法和apply()
方法类似,只有一个区别,就是call()
方法接受的是一个参数列表,而apply()
方法接受的是一个包含多个参数的数组。-
语法
function.call(thisArg, arg1, arg2, ...)
-
参数
thisArg
可选的。在
function
函数运行时使用的this
值。请注意,this
可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为null
或undefined
时会自动替换为指向全局对象,原始值会被包装。 -
arg1, arg2, ...
指定的参数列表。
-
返回值
使用调用者提供的
this
值和参数调用该函数的返回值。若该方法没有返回值,则返回undefined
。
-
-
bind()
方法创建一个新的函数,在bind()
被调用时,这个新函数的this
被指定为bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。-
语法
function.bind(thisArg, arg1, arg2, ...)
-
参数
thisArg
调用绑定函数时作为
this
参数传递给目标函数的值。 如果使用new
运算符构造绑定函数,则忽略该值。当使用bind
在setTimeout
中创建一个函数(作为回调提供)时,作为thisArg
传递的任何原始值都将转换为object
。如果bind
函数的参数列表为空,或者thisArg
是null
或undefined
,执行作用域的this
将被视为新函数的thisArg
。 -
arg1, arg2, ...
当目标函数被调用时,被预置入绑定函数的参数列表中的参数。
-
返回值
返回一个原函数的拷贝,并拥有指定的
this
值和初始参数。
-
call、apply和bind函数存在的区别:
bind返回对应函数, 便于稍后调用; apply, call则是立即调用。
除此外, 在 ES6 的箭头函数中, call 和 apply 将失效, 对于箭头函数来说:
- 箭头函数体内的 this 对象, 就是定义时所在的对象, 而不是使用时所在的对象;所以不需要类似于
var _this = this
这种丑陋的写法 - 箭头函数不可以当作构造函数,也就是说不可以使用 new 命令, 否则会抛出一个错误
- 箭头函数不可以使用 arguments 对象,,该对象在函数体内不存在. 如果要用, 可以用 Rest 参数代替
- 不可以使用 yield 命令, 因此箭头函数不能用作 Generator 函数