几种创建对象的方式

创建object对象主要有字面量创建、new和object.create()三种方式

一、字面量创建

var objA = {};
objA.name = 'a';
objA.sayName = function() {
    console.log(`My name is ${this.name} !`);
}
// var objA = {
//     name: 'a',
//     sayName: function() {
//         console.log(`My name is ${this.name} !`);
//     }
// }
objA.sayName();
console.log(objA.__proto__ === Object.prototype); // true
console.log(objA instanceof Object); // true

二、new

     new创建的步骤:首先会内部创建一个object空对象,然后把object的隐式原型指向构造函数的显式原型,再借用call改变this的指向,执行构造函数,最后判断执行结果返回的类型,若是object类型,则new返回这个结果,若不是则返回空object对象。

function mynew(fn){
    //创建新对象
    var obj = {}

    //obj隐式原型指向传入的fn的显式原型
    obj.__proto__ = fn.prototype

    //改变this指向,注意用call后面参数的处理
    let result = fn.call(obj, Array.from(arguments).slice(1))

    //判断返回结果
    return result instanceof object ? result : obj
}

       所以字面量创建和new创建的主要区别就是:new创建的效率没有字面量创建高,因为new内部多执行了代码。但他们最后创建的对象都是object的实例且objA.__proto__ === Object.prototype为true

三、object.create()

     它会让新创建对象的隐式原型指向一个现有对象

const person = {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};
const me = Object.create(person); // me.__proto__ === person
me.name = "Matthew"; // name属性被设置在新对象me上,而不是现有对象person上
me.isHuman = true; // 继承的属性可以被重写
me.printIntroduction(); // My name is Matthew. Am I human? true

object.create(proto, [propertiesObject])

proto: 必传,是新创建对象的隐式原型

[propertiesObject]:可选,定义新创建对象里的一些属性和方法,注意:不是在隐式原型上定义                                    的,而是在新创建对象上定义的,可以用hasOwnProperty()访问到

注意:若proto为null,则新创建的对象是一个空对象,不会继承object.prototype上的属性和方法

var bb = Object.create(null, {
    a: {
        value: 2,
        writable: true,
        configurable: true
    }
});
console.dir(bb); // {a: 2}
console.log(bb.__proto__); // undefined
console.log(bb.__proto__ === Object.prototype); // false
console.log(bb instanceof Object); // false 没有继承`Object.prototype`上的任何属性和方法,所以原型链上不会出现Object

// ----------------------------------------------------------

var cc = Object.create({b: 1}, {
    a: {
        value: 3,
        writable: true,
        configurable: true
    }
});
console.log(cc); // {a: 3}
console.log(cc.hasOwnProperty('a'), cc.hasOwnProperty('b')); // true false 说明第二个参数设置的是新对象自身可枚举的属性
console.log(cc.__proto__); // {b: 1} 新对象cc的__proto__指向{b: 1}
console.log(cc.__proto__ === Object.prototype); // false
console.log(cc instanceof Object); // true cc是对象,原型链上肯定会出现Object

通过object.create()创建的对象它依然是object的实例(null除外)但cc.__proto__ === Object.prototype // false

手写object.create()

function create(F,property){
    //内部新创建一个函数
    var f = function() { }
    //新创建函数的显式原型指向传入的对象,这样f实例的隐式原型会指向F
    f.prototype = F

    let result = new f()
    
    //将传入的自定义属性复制
    if(property){
        Object.assign(result,property)
    }

    //输出f的实例
       return result
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值