实现原理
// new操作符实现原理
function news(func){
var target = {} //生成一个新是对象
target.__proto__ = func.prototype; //实例的__proto__指向原型,构造函数的prototype也指向原型
var res = func.call(target); //把函数的this绑定在了新生成的对象中
if(typeof (res) == 'object' || typeof (res) == 'fucntion'){
return res;//如果传入的函数(构造函数)有自己的返回值,则返回该值
}
return target; //如果传入的函数(构造函数)没有自己的返回值,则返回新对象
}
原型、实例、构造函数的关系:
- 原型(prototype):
一个简单的对象,用于实现对象的继承属性。可以简单理解成对象的"父亲"。在火狐和谷歌中,每个js对象都包括一个__proto__
(非标准)的属性指向该对象原型(也就是它的"父亲"),可以obj.__proto__
进行访问。 - 构造函数:
可以通过new来新建一个对象的函数 - 实例:
通过构造函数和new创建出来的对象,就是实例。实例通过==proto==指向原型,通过constructor
指向构造函数。
function Func(){
let arr = [1,2,3,4,5]
return arr;
}
const instance = new Func()
以函数Func
为例,函数Func
就是一个构造函数,我们可以通过它构建一个实例。此时,instance
为实例,构造函数为Func
,构造函数有一个prototype
的属性指向原型。所以原型就是:
const prototype = Func.prototype
三者的关系:
实例.__proto__ === 原型
原型.constructor === 构造函数
构造函数.prototype === 原型
实例.constructor === 构造函数
例子:
function instanceFunc(){
this.people = ["张三丰","张思枫","张五分","张流风 "]
}
const instance = new Func();
console.log(instanceFunc.prototype.constructor);
console.log(instance.__proto__,'实例访问原型');
console.log(instanceFunc.prototype,'构造函数访问原型');
console.log(instance.constructor,'实例的构造函数');
new操作构造函数生成实例的过程
- 首先, 当我们使用new操作符时, js会先创建一个空的对象
- 然后, 构造函数中的this指向该空对象
- 其次, 在构造函数中通过操作this, 来给这个空对象赋予相应的属性
- 最后, 返回这个经过处理的"空对象"(此时, 对象已经不是空的了)
new操作构造函数的注意事项
- 如果构造函数的返回值是一个原始类型(非引用对象, 如字符串), 那么返回值为new创建的"空对象"
var obj = new function() { return "code";};
alert(obj); // [object object]
console.log(obj); //{}
- 如果构造函数的返回值是一个引用对象(数组, 对象, 函数等), 那么返回值会覆盖new创建的"空对象"
var obj = new function() { return new String("code"); };
alert(obj); // "code"
console.log(obj); //[String: 'code']
function NewFunc(func){
var ret = {};
if (func.prototype !== null) {
ret.__proto__ = func.prototype;
}
var ret1 = func.apply(ret, Array.prototype.slice.call(arguments, 1));
if ((typeof ret1 === "object" || typeof ret1 === "function") && ret1 !== null)
{
return ret1;
}
return ret;
}