重写内置的NEW和Object.create

重写内置的new和Object.create

重写内置的new

new 一个函数所具备的功能

  • new 一个函数执行的时候,是把他当做构造函数执行的
  • 先创建一个类,再创建一个类的实例,在当前实例的执行上下文中会默认创建一个对象,让函数体当中的this指向这个对象
  • 函数正常执行完毕,最后看函数当中有没有return
    • 如果没有return,默认把实例返回
    • 如果有return, 看返回的数据类型
  • 如果返回的是值类型,则依旧返回默认的当前实例
  • 如果返回的是引用类型值,则用返回的引用类型值替换默认的当前实例

EG:实现以下效果

function Dog(name) {
    this.name = name;
}
Dog.prototype.bark = function () {
    console.log('wangwang');
}
Dog.prototype.sayName = function () {
    console.log('my name is ' + this.name);
};
let sanmao = _new(Dog, '三毛');
sanmao.bark(); //=> "wangwang"
sanmao.sayName(); //=>"My name is 三毛"
console.log(sanmao instanceod Dog); //=> true
/*
 * _new:创建摸一个类的实例
 * params:
 *    Func:创建实例的这个类
 *    ...args:剩余的参数都是给Func这个函数传递的实参 
 */
function _new(Func, ...args) {   
/* 思路:
*   1. 创建Func的一个实例对象(对象.__proto__=== Func.prototype) 
* 		1)obj = {};  obj.__proto__ = Func.prototype;
* 		2) obj = Object.create(Func.prototype);  
* 	2. 把类当做普通函数执行(THIS指向的是实例对象):result = Func.call(obj, ...args);
* 	3. 看一下函数执行是否存在返回值,不存在或者返回的是值类型,则默认返回实例,如果返回的是引用数据类型则返回的不是实例而且自己写的引用类型值:if (result !== null && /^(object|function)$/.test(typeof result)) {return result;}; return obj;
*/
	let obj,
		result,
		proto = Func.prototype,
		ct = typeof Func;
	//校验规则
	if(Func === Symbol || Func === BigInt || typeof proto !== "function" || !proto ){
		throw new TypeError(` ${Func} is not a constructor ! `);
	};
    obj = Object.create(Func.prototype);  
    result = Func.call(obj, ...args);
    if (result !== null && /^(object|function)$/.test(typeof result)) {return result;};
    return obj;
};

Object.create()

  • 语法:let obj1 = Object.create([obj]);
  • 意义:创建一个空对象(obj1) , 并且让obj1.__proto__指向 [obj], 把 [obj] 作为实例对象的原型
  • [obj]:可以是一个对象或者是null,但是不能是其他值
  • eg:obj = Object.create(Func.prototype); (上例中创建一个空的类)

重写Object.create

/*
 * 重写Object.create:创建某个类的空实例
 */
Object.create = function create(prototype) {
	if(prototype !== null && typeof prototype !== "object" ) throw new TypeError("Object prototype may only be an Object or null");
    function Proxy() {};
    Proxy.prototype = prototype;
    return new Proxy;
};

Object.create(null) VS Object.create({})

var obj = Object.create(null);// 把obj.__proto__去掉了,浏览器断开了内置的原型链查找(破坏了原始的机制)
obj.__proto__ = Array.prototype;// 这仅仅是给obj设置了一个私有的属性__proto__
console.log(obj.slice);// 私有属性中没有slice  =>undefined 
 
var obj = Object.create({}); //=>这样不会破坏内置的原型链查找机制
obj.__proto__ = Array.prototype;
console.log(obj.slice); 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值