zoukankan      html  css  js  c++  java
  • js学习日记-new Object和Object.create到底干了啥

    function Car () {
        this.color = "red";
    }
    Car.prototype.sayHi=function(){
      console.log('你好')
    }
    var car =new Car(); var car2 = Object.create(Car);

    new XXX()时发生了什么?

    var obj={};
    obj.__proto=Car.prototype
    Car.call(obj)
    

    第一步,创建了一个空对象obj
    第二步,将空对象的__proto__成员指向了Car函数的原型属性,该原型属性是一个原型对象,也就意味着obj的原型属性上拥有了Car.prototype中的属性或方法

    第三步,将Car函数中的this指针指向obj,obj有了Car构造函数中的属性或方法 ,然后Car函数无返回值或返回的不是对象,直接返回obj,否则返回Car函数中的对象


    tip:__proto__是什么

    每个对象都有一个[[prototype]}属性,这个属性是隐藏属性,谁创建了它,该属性就指向谁的prototype属性,因为是隐藏属性,不能直接访问,所以有的浏览器提供了一个__proto__属性来访问,然而这不是一个标准的访问方法,所以ES5中用Object.getPrototypeOf函数获得一个对象的[[prototype]]。ES6中,使用Object.setPrototypeOf可以直接修改一个对象的[[prototype]]

    Object.create时发生了什么?

    Object.create()方法创建一个新对象,并使用现有的对象来提供新创建的对象的__proto__,关键代码如下

    关键代码如下:

    Object.create =  function (o) {
        var F = function () {};
        F.prototype = o;
        var newObj=new F();
        return newObj;
    };

    可以看到Object.create内部创建了一个新对象newObj,默认情况下newObj.__proto__== F.prototype,在本例中则重写了构造函数F的原型属性,最终的原型关系链为newObj.__proto__== F.prototype == o

    如果现有的对象是一个构造函数,即var car2=Object.create(Car)会发生什么呢?

    console.log(car2.color)    //undefined
    console.log(car2.sayHi())  //undefined
    

    执行代码发现都是undefined, 为什么会这样呢?

    问题1:因为Object.create内部的新对象是new F()创建的,跟Car构造函数没有半毛钱的关系,所以自然不能访问到Car中的属性了

    问题2:调用car2.sayHi()时首先判断car2对象有没有相应的方法,如果没有,则查找car2的原型链上有没有该方法,car2的原型属性是Car构造函数(可以通过car2.__proto__来证明),构造函数没有sayHi方法,自然也就是undefined了。

    那如果将var car2=Object.create(car)又发生了什么呢?

    function Car () {
        this.color = "red";
        this.person={name:'张三'}
    }
    Car.prototype.sayHi=function(){
      console.log('你好')
    }
    var car =new Car();
    var car2 =  Object.create(car);
    car2.person.name ='李四'
    console.log(`car是${car.person.name},car2是${car2.person.name}`)
    

    相当于实现了原型继承方式(注意不是原型链继承),本质上来说是对一个对象进行了浅拷贝  


    最终结论:

    1. Object.create(o),如果o是一个构造函数,则采用这种方法来创建对像没有意义

    2.Object.create(o),如果o是一个字面量对象或实例对象,那么相当于是实现了对象的浅拷贝

  • 相关阅读:
    mysql--连接查询(内外连接)
    Mysql--select基础查询
    Mysql--数据定义语言(DDL)
    Mysql--数据操作语言(DML)
    java--String、StringBuilder、StringBuffer的解析和比较?
    Java--equals和 == 的比较和equals()、HashCode()的重写
    Mysql--数据类型
    Mysql--约束
    SpringCloud版本说明
    springBoot 发送邮件
  • 原文地址:https://www.cnblogs.com/94pm/p/9113434.html
Copyright © 2011-2022 走看看