Open zhaobinglong opened 3 years ago
为什么this会指向a?首先new关键字会创建一个空的对象,然后会自动调用一个函数apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。
var user = 'kkk'
function Fn(){
this.user = "追梦子";
}
var a = new Fn();
console.log(a.user); //追梦子
原本的构造函数是window对象的方法,如果不用new操作符而直接调用,那么构造函数的执行对象就 是window,即this指向了window。现在用new操作符后,this就指向了新生成的对象。理解这一步至关重要
1、创建一个空对象 obj 2、将该对象 obj 的原型链 proto 指向构造函数的原型 prototype, 并且在原型链 proto 上设置 构造函数 constructor 为要实例化的 Fn 3、传入参数,并让 构造函数 Fn 改变指向到 obj,并执行 4、最后返回 obj
function myNew(Fn) {
let obj = {} // 新建空对象
let arg = Array.prototype.slice.call(arguments, 1) // 取出参数,从第二个开始,转为数组
obj.__proto__ = Fn.prototype // 新对象的原型属性指向旧对象的原型对象
obj.__proto__.constructor = Fn
let ret = Fn.apply(obj, arg) // 执行一下
return typeof ret === 'object' ? ret || obj : obj
}
本质上并无区别,唯一的区别有两个:
本质上,箭头函数体内的this对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象。
//换成箭头函数
let obj={
name:"kk",
fn:function(){
setTimeout(()=>{console.log(this.name)});
}
}
obj.fn(); // kk
let obj={
name:"kk",
fn:function(){
setTimeout(function(){console.log(this.name)});
}
}
obj.fn(); // undefined
箭头函数没有自己的this值,它的this值来自其所在的词法作用域
Function.prototype.call_ = function (obj) {
var args = [];
// 注意i从1开始
for (var i = 1, len = arguments.length; i < len; i++) {
args.push("arguments[" + i + "]");
};
obj.fn = this; // 此时this就是函数fn
eval("obj.fn(" + args + ")"); // 执行fn
delete obj.fn; //删除fn
};
Function.prototype.apply_ = function (obj, arr) {
obj = obj ? Object(obj) : window;
obj.fn = this;
if (!arr) {
obj.fn();
} else {
var args = [];
// 注意这里的i从0开始
for (var i = 0, len = arr.length; i < len; i++) {
args.push("arr[" + i + "]");
};
eval("obj.fn(" + args + ")"); // 执行fn
};
delete obj.fn; //删除fn
};
function fun() {
alert(this);
}
fun.call(null); // window or global
this的本质
this就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。
this的指向
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象
this指向的四种情况
a.如果是一般函数,this指向全局对象window; b.在严格模式下"use strict",为undefined. c.对象的方法里调用,this指向调用该方法的对象. d.构造函数里的this,指向创建出来的实例.
实例1
参考
https://www.cnblogs.com/pssp/p/5216085.html http://www.ruanyifeng.com/blog/2018/06/javascript-this.html