JavaScript – this的使用
详细内容请关注我的博客地址
通过阅读MDN和各类博客复习了一下javascript中this的使用方法
什么是this
在传统的面向对象语言中this关键字指代了当前对象本身,或者是当前对象的一个实例,通过使用this可以对其中方法与属性进行调用
在javascript中this的指向是临时决定的,而不是在创建时决定的,大多数情况下函数的调用方式决定了this的指向
全局环境中的this
无论是否处于严格模式下,在全局环境中this都唯一指向全局对象window(浏览器下)
console.log(this === window); //true
var a = 3;
console.log(a); //3
console.log(this.a) //3
函数环境下的this
直接调用
- 在非严格模式下直接调用函数,则函数中的this指向全局
- 在严格模式下调用函数,则此函数中的this会被赋值为undefined
- 非严格模式
function foo() {
return this;
}
console.log(foo() === window); //true
- 严格模式
function foo() {
"use strict"//声明严格模式
return this;
}
console.log(foo() === undefined); //true
call(),apply()
在js中可以使用call()或者apply()函数改变this的指向
var person = {
name: "sleepy-god",
age: 20
};
function say(job) {
console.log(this.name + ":" + this.age + "-" + job);
}
say.call(person, "student"); //sleepy-god:20-student
say-apply(person, ["student"]); //sleepy-god:20-student
- Function.prototype中的call()和apply都可以改变this的指向,将this值绑定到调用中的特定对象
- call()与apply()作用相同,唯一的不同点就是apply()接收的参数必须时数组形式的
bind()
bind的用法与call()和apply()类似
this
将永久地被绑定到了bind
的第一个参数,无论这个函数是如何被调用的。
function.bind(thisArg[, arg1[, arg2[, ...]]])
与call()和apply()不同的是call和apply会自动执行函数,而bind()不会,bind()会返回一个函数引用
下面附上一段摘自MDN的源码实现:
if(!Function.prototype.bind){
(function() {
var slice = Array.prototype.slice;
Function.prototype.bind = function() {
var thatFunc = this,
thatArg = arguments[0];
var args = slice.call(arguments, 1);
if(typeof thatFunc !== 'function') {
throw new TypeError('Function.prototype.bind - ' +
'what is trying to be bound is not callable');
}
return function() {
var funArgs = args.concat(slice.call(arguments))
return thatFunc.apply(thatArg, funcArgs)
}
}
})()
}
- 将
Array.prototype.slice
赋值给变量slice - 将bind()传入的第一个参数
arguments[0]
记录下来,这是要绑定的this,然后将后续参数保存到args变量中 - bind()方法返回的是一个函数,funArgs就是将bind()传入的剩余参数和后续返回的函数执行时加入的参数进行拼接
- 然后将this指向之前的第一个参数
arguments[0]
关于面试中常见的手写call()和apply()方法题目
浏览了不少博客和文章,发现手写call(),apply(),和bind()是比较常见的面试题目,因此我也总结了一下call()和apply()的方法
手动实现call()方法
Function.prototype.myCall = function(context) {
if(typeof context === 'undefined' || context === null) {
context = window
}
context.fn = this;
let args = [...arguments].slice(1);
let result = context.fn(...args);
delete context.fn
return result
}
手动实现apply()方法
Function.prototype.myApply = function(context) {
if(typeof context === 'undefined' || context === null) {
context = window
}
context.fn = this;
let args = arguments[1];
let result;
if(args) {
result = context.fn(...args)
} else {
result = context.fn()
}
delete context.fn;
return result
}
参考链接: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind