1.用什么样的思路可以new关键词
2.apply、call、bind方法区别
3.实现apply、call、bind、new
new原理介绍
new作用:执行一个构造函数、返回一个实例对象。
分为四步:
1.创建一个新对象
2.将构造函数的作用域赋给新对象 (this指向新对象)
3.指向构造函数中代码(为这个新对象添加属性)
4.返回新对象
function Person(){
this.name='Jack';
return {age:18}
}
var p = new Person();
console.log(p) // {age: 18}
console.log(p.name) // undefined
console.log(p.age) // 18
当构造函数最后return出来的是一个和this无关的对象时,new会直接返回这个新对象,而不是通过new执行步骤生成的this对象。
当返回的不是对象,还是会按照new的实现步骤,返回新生成的对象。
new 关键词执行之后总是会返回一个对象,要么是实例对象,要么是return语句指定的对象。
function _new(ctor,...args){
let obj=new Object();
obj.__prototo__=Object.create(ctor.prototype)
let res=ctor.apply(obj,[...args])
let isObject=typeof res==='object' && res!==null;
let isFunction =typeof res==='function'
return isObject || isFunction?res :obj;
}
apply & call & bind原理介绍
A对象有个getName的方法,B对象也需要临时使用同样的方法,b对象可以借用a对象的getName方法。
let a = {
name: 'jack',
getName: function(msg) {
return msg + this.name;
}
}
let b = {
name: 'lily'
}
console.log(a.getName('hello~')); // hello~jack
console.log(a.getName.call(b, 'hi~')); // hi~lily
console.log(a.getName.apply(b, ['hi~'])) // hi~lily
let name = a.getName.bind(b, 'hello~');
console.log(name()); // hello~lily
apply和call的实现
Function.prototype.call=function(context,...args){
var context=context || window
context.fn=this;
var result=eval('context.fn(...args)');
delete context.fn
return result;
}
Function.prototype.apply(context,args){
var context=context || window;
context.fn=this
var result=eval('context.fn(...args)')
delete context.fn;
return result;
}
function person(a,b){
console.log(this.name)
console.log(a,b)
}
var egg={name:"a"}
Function.prototype.bind(context,...args){
var self=this;
var found=function(){
self.apply(this instanceof self?this:context,args.concat(Array.prototype.slice.call(arguments)))
}
if(this.prototype){
fbound.prototype=Object.create(this.prototype);
}
return fbound;
}