new 运算符建立一个用户定义的对象类型的实例或具备构造函数的内置对象的实例。bash
举个栗子函数
function Car(color) {
this.color = color;
}
Car.prototype.start = function() {
console.log(this.color + " car start");
}
var car = new Car("black");
car.color; // 访问构造函数里的属性
// black
car.start(); // 访问原型里的属性
// black car start
复制代码
能够看出 new 建立的实例有如下 2 个特性ui
访问到构造函数里的属性this
访问到原型里的属性spa
注意点prototype
ES6新增 symbol 类型,不能够使用 new Symbol(),由于 symbol 是基本数据类型,每一个从Symbol()返回的 symbol 值都是惟一的。3d
Number("123"); // 123
String(123); // "123"
Boolean(123); // true
Symbol(123); // Symbol(123)
new Number("123"); // Number {123}
new String(123); // String {"123"}
new Boolean(true); // Boolean {true}
new Symbol(123); // Symbol is not a constructor
复制代码
new操做符的工做原理code
废话很少说,直接上代码
var newObj = function(func){
var t = {}
t.prototype = func.prototype
var o = t
var k =func.call(o);
if(typeof k === 'object'){
return k;
}else{
return o;
}
}
var parent1 = newObj(Parent) //等价于new操做
复制代码
DEMO:cdn
/**
* new2 new关键字的代码实现演示
* @param {function} func 被new的类 (构造函数)
*/
function new2(func) {
// 建立了一个实例对象 o,而且这个对象__proto__指向func这个类的原型对象
let o = Object.create(func.prototype);
// (在构造函数中this指向当前实例)让这个类做为普通函数值行 而且里面this为实例对象
let k = func.call(o);
// 最后再将实例对象返回 若是你在类中显示指定返回值k,
// 注意若是返回的是引用类型则将默认返回的实例对象o替代掉
return typeof k === 'object' ? k : o;
}
// 实验
functionM() { // 即将被new的类
this.name = 'liwenli';
}
let m = new2(M); // 等价于 new M 这里只是模拟
console.log(m instanceof M); // instanceof 检测实例
console.log(m instanceof Object);
console.log(m.__proto__.constructor === M);
复制代码
Object.create 兼容实现对象
let obj1 = {id: 1};
Object._create = (o) => {
let Fn = function() {}; // 临时的构造函数
Fn.prototype = o;
return new Fn;
}
let obj2 = Object._create(obj1);
console.log(obj2.__proto__ === obj1); // true
console.log(obj2.id); // 1
// 原生的Object.create
let obj3 = Object.create(obj1);
console.log(obj3.__proto__ === obj1); // true
console.log(obj3.id); // 1
复制代码
完整代码:
function new2(MyFun, ...list) {
let o = Object.create(MyFun.prototype);
let k = MyFun.call(o, ...list);
return typeof k === 'object' ? k : o;
}
function Car(color, name) {
this.color = color;
this.name = name;
return "new car";
}
Car.prototype.fun=function(){
console.log(this.color,this.name)
}
var obj=new2(Car,123,'小花');
console.log(obj)
console.log(obj.__proto__===Car.prototype);
console.log(Car.prototype.isPrototypeOf(obj))
console.log(Object.prototype.isPrototypeOf(obj))
console.log(obj instanceof Car)
console.log(obj.constructor===Car)
复制代码
有什么问题?
typeof k === 'object'
若是k为null怎么办?function new2(MyFun, ...list) {
if(!MyFun) throw new Error("第一个参数必须是函数");
let o = Object.create(MyFun.prototype);
let k = MyFun.call(o, ...list);
return k&&(typeof k === 'object') ? k : o;
}
function Car(color, name) {
this.color = color;
this.name = name;
return null;
}
Car.prototype.fun=function(){
console.log(this.color,this.name)
}
var obj=new2(Car,123,'小花');
console.log(obj)
console.log(obj.__proto__===Car.prototype);
console.log(Car.prototype.isPrototypeOf(obj))
console.log(Object.prototype.isPrototypeOf(obj))
console.log(obj instanceof Car)
console.log(obj.constructor===Car);
var obj=new2(null,123,'小花');
复制代码