js语言this指向
指向特性
// 输出 window
console.log(this)
// 输出 window
function fun() {
console.log(this)
}
fun() // <=> [this.]fun()
// 输出 window
function fun() {
function fun() {
console.log(this)
}
fun()
}
fun() // <=> [this.]fun()
// 输出 obj
let obj = {
fun: function() {
console.log(this);
}
}
obj.fun()
以上证明this
指向它的执行对象
绑定类型
指定了绑定对象称为显式绑定,没有指定称为隐式绑定,除此还有绑定丢失
var obj = {
fun: function() {
console.log(this)
}
}
let fun = obj.fun // fun 作为实参赋值,执行对象将成为其绑定对象
fun() // 输出 window
let obj = {
fun: function() {
console.log(this)
}
}
function run(fun) {
fun()
}
run(obj.fun) // 输出 window
切换绑定
绑定函数有:call
, apply
, bind
// 绑定示例
function Person() {
console.log(this.name)
}
let student = {
name: "zhangSan"
}
Person.call(student)
// 3个绑定函数区别
let person = {
name: "zhangSan",
say: function(age, phone) {
console.log(this.name)
console.log(age)
console.log(phone)
}
}
let person2 = {
name: "liSi"
}
person.say.call(person2, "age", "phone")
person.say.apply(person2, ["age", "phone"]) // 参数以数组传递
person.say.bind(person2, "age", "phone") // 得到一个函数而非直接执行
构造函数指向
// 构造函数中的this指向新建对象
function person(name, age) {
this.name = name
this.age = age
}
let person1 = new person("zhangSan", 20)
call 的实现
先用最基础的代码解释原理
// 测试用
let person = {
name: 'zhangSan'
}
let obj = {
name: 'kiSi',
fun: function() {
console.log(this.name)
}
}
// 添加 call2 原型
Function.prototype.call2 = function(context) {
context.p = this
/**
* 此 this 指向 obj.fun,即调用者
* 修改后为
* context: { name: 'zhangSan', p: function(){ /*...*/ } }
*/
context.p()
// 此时调用p, p中的this指向context本身
}
obj.fun.call2(person)
原理如上,懂了原理再完善一下代码:
- 如果 context.p 原本就存在,call2 会干扰原对象,此时可用 Symbol 创建唯一 Key
- 要能传参数
- 健壮性保证,对 context 进行预处理
Function.prototype.call2 = function(context, ...args) {
if(context === null || context === undefined) {
context = window
}else {
context = Object(context) // 值为原始值(数字, 字符串, 布尔值)的 this 会指向该原始值的实例对象
}
const p = Symbol('随便写')
context[p] = this
let result = context[p](...args)
delete context[p] // 从对象中删除临时函数
return result
}
obj.fun.call2(person, 18, "nv")
手写call原文参考:https://www.cnblogs.com/web-chuan/p/11592261.html
如有侵权,立即删除