函数中运行时产生了什么
函数运行时, 会主动绑定两个变量 arguments 和 this
arguments: 一个实参的类数组对象
function Aoo(a, b){console.log(arguments);
}
// 这里的 a,b 是形参
Aoo(1, 2, 3, 4) // 1,2,3,4
// 这里的 arguments 就是 1,2,3,4 这个就是实参
this: 函数运行时的上下文
谁调用这个办法,this 就指向谁
function Aoo(){console.log(this);
}
let obj = {
fn: Aoo,
obj2: {fn: Aoo}
}
Aoo(); // window 在浏览器环境下
obj.fn(); // obj
obj.obj2.fn(); // obj2
扭转 this 指向的办法
function.call(obj,arg1,arg2,….)
function.apply(obj,[arg1,arg2,….])
function Aoo(){console.log(this.name)
}
window.name = 'window'
Aoo();// window
let obj = {name: 'objName'}
Aoo.call(obj) // objName
Aoo.apply(obj) // objName
// 如果前面带参数的话
function Boo(arg1,arg2){
this.a = arg1;
this.b = arg2;
console.log(this);
}
Boo('1', '2');//window.a === '1' windwo.b === '2'
let obj2 = {name: 'obj2'}
Boo.call(obj2, '1', '2') //{name: "obj2", a: "1", b: "2"}
Boo.apply(obj2, ['1', '2']) //{name: "obj2", a: "1", b: "2"}
new 一个对象时产生了什么
首先, 咱们须要晓得 JS 的原型链
function Person(name){this.name = name;}
// 咱们将 Person 这个函数的公共办法写在 prototype 上, 前面通过 Person 函数 new 进去的实例都能够应用这些办法
Person.prototype.introduct = function(){console.log(`Hello, my name is ${this.name}`)
}
let p = new Person('jack');
p.introduct();//Hello, my name is jack
// 为什么能够实现呢
// 因为 p.__proto__ === Person.prototype, 当 p 实例上找不到 introduct 这个办法时, 就会顺着__proto__去寻找原型对象上是否存在这个办法
理解原型链后, 探索一下 new 一个对象时产生了什么
function Person(name){this.name = name;}
let p = new Person('rose')// {name: "rose", __proto__: Object}
//1. 创立一个空对象
let obj = {};
//2. 将这个空对象的__proto__指向构造函数的 prototype
obj.__proto__ = Person.prototype;
//3. 将构造函数的 this 指向这个空对象
//4. 运行构造函数
Person.call(obj, name)
//5. 返回这个对象
return obj;
// 通过这 5 步, 咱们就能够产生一个由构造函数 new 进去的实例