实现new方法
new可以用来构造一个实例,有以下步骤
- 创建一个新对象
- 新对象的原型proto指向构造函数的原型
- 执行构造函数
判断构造函数返回值是否是对象或者函数,如果是返回返回值,如果不是,返回这个新对象
function New(constructor) {
const object = constructor.prototype === null ? {} : Object.create(constructor.prototype);
let res = null;
if (typeof constructor === 'function') {
res = constructor.apply(object, Array.prototype.slice.call(arguments, 1));
}
if (res !== null && (typeof res === 'object' || typeof res === 'function')) {
return res;
}
return object;
}
对象字面量{}与Object.create(null)区别:
对象字面量与new Object()是一样的,都有Object.prototype的原型,可以正常使用对象的属性
- Object.create(null)是创建一个原型为null的对象,没有原型链
区分使用new调用构造函数还是普通调用
构造函数中this指向,new调用时this指向实例,普通调用this指向window或undefined
function Person() {
if (this instanceof Person){
// new调用
}
}
通过constructor,new调用时constructor指向构造函数,普通调用时,constructor指向Object
function Person() {
if (this.constructor === Person){
// new调用
}
}
通过new.target,new调用时new.target指向构造函数,普通调用时指向undefined
function Person() {
if (new.target === Person){
// new调用
}
}
实现Object.create
Object.create主要就是创建一个以传参作为原型的对象
function create(proto, propertyObject) {
const F = function () { };
F.prototype = proto;
const obj = new F();
if (propertyObject) {
Object.defineProperties(obj, propertyObject)
}
return obj;
}
实现instanceOf
instanceOf主要判断实例是否是某个构造函数的实例,只要该构造函数的原型在实例的原型链上,都会返回true
function instanceOf(instance, constructor) {
let proto = instance.__proto__;
while (proto !== null) {
if (proto === constructor.prototype) {
return true;
}
proto = proto.__proto__;
}
return false;
}
实现call和apply
call和apply都是改变this的指向并立即执行,区别在于传参的个数,实现原理就是把函数绑在context上后调用 ```javascript function call(context, …args) { if (!context || typeof context !== ‘object’) return; const key = new Symbol(); context[key] = this; const result = contextkey; delete context[key]; return result; }
function apply(context, args) { if (!context || typeof context !== ‘object’) return; const key = new Symbol(); context[key] = this; const result = contextkey; delete context[key]; return result; }
<a name="Ahebs"></a>
# 实现bind
bind也是改变this的指向,不过不会立即执行,而是返回一个函数,bind功能如下
- 改变原有this指向
- 返回该函数的拷贝
- 当使用new 调用绑定后的函数时,之前绑定的this无效,new操作符修改this的优先级更高
```javascript
function bind(context) {
if (!context || typeof context !== 'object') return;
if (typeof this !== 'function') return;
const self = this;
const args = Array.prototype.slice.call(arguments, 1);
const func = function () {
self.apply((this instanceof self) ? this : context, args.concat(Array.prototype.slice.call(arguments)));
}
func.prototype = Object.create(this.prototype);
return func;
}