zoukankan      html  css  js  c++  java
  • constructor、prototype、isPrototypeOf、instanceof、in 、hasOwnProperty

    constructor、prototype、isPrototypeOf、instanceof、in 、hasOwnProperty等等

    constructor:对象构造器。存在于原型对象中?,相当于php中的基类中的构造方法?可以获取构造函数本身

    prototype:访问对象构造器的原型,只有函数才具有这个属性。

    isPrototypeOf:如果对象 A 存在于 对象obj的原形链中,则 A.prototype.isPrototypeOf(obj)返回true,而obj必定继承了A 的属性。

           判断实例化的对象box是否指向了原型对象,基本上只要实例化了,实例化的对象会自动指向构造函数()

    __proto__:访问对象的原型链在当前对象的上一级对象,即对象的父级对象,非W3C 或 ECMAscript 标准,是浏览器对原型继承的一种实现手段,存在于firefox 和 chrome ,IE下不存在这个属性。

    在对象的继承关系中,对象obj的构造器 constructor 其实是存在于原型链中的,

    即 obj.constructor 实际上是 obj.__proto__.constructor,  obj.hasOwnProperty('constructor');  为 false

    function Y() {this.y=99;}

    var obj = new Y(); 

    console.log(obj.constructor); //Y

    console.log(obj.hasOwnProperty('constructor')); //false

    console.log(obj.__proto__.hasOwnProperty('constructor')); //true

    //=====

    function X(){this.x=88; }

    function Y() {this.y=99;}

    Y.prototype = new X();

    var obj = new Y(); 

    console.log(obj.constructor); //X

    console.log(obj.hasOwnProperty('constructor'));//false

    console.log(obj.__proto__.hasOwnProperty('constructor')); //false

    console.log(obj.__proto__.__proto__.hasOwnProperty('constructor')); //true

    访问对象时,对于 obj.__proto__.x=value 则必定有 obj.x=value,

    obj.constructor.prototype 上的属性将被保存在obj.__proto__中。

      function Y() {this.y=99;} 

      Y.prototype = {a:11};

      var obj = new Y(); 

    obj.__proto__.hasOwnProperty("a");//true

      Y.prototype.a=77;

      console.log([obj.a,obj.__proto__.a,obj.y,obj.__proto__.y]);  

      /*77,77,99,obj.__proto__.y 是 undefined,y 属性是由对象构造器直接产生的而不是从原形链继承来的*/

      new 运算构造obj对象之后,obj访问继承来的属性时,是通过__proto__ 访问的,而不是通过obj.constructor.prototype 访问,

      因此,如果修改obj.constructor.prototype指向另一个对象,并不会影响obj继承原有的属性。

      Y.prototype = {b:22};

      console.log(obj.b); //undefined

      console.log(obj.a); //77

    in: 如果对象 obj  有属性 property(包括继承来的和不可列举属性,不同于 for in 循环中的 in,for in 忽略了不可列举属 性), 则'property' in obj 返回 true,这个运算不存在于初期版本的javascript。

    propertyIsEnumerable: 如果对象obj上的属性property可以被列举出来(可被 for in 循环遍历), 则 obj.propertyIsEnumerable('property') 返回true,值得注意的 是,propertyIsEnumerable对继承来的属性一律判断为false,这一般被认为是ECMA Script 规范的一个设计上的错误。

    hasOwnProperty:如果对象obj 上的属性 property 不是继承的来的,则 obj.hasOwnProperty('property') 返回true。

    delete: 删除对象自身上的属性,不能删除继承来的属性,不能通过 delete window.x 来删除使用 var 声明的全局变量 x,也不能函数函数声 明,在的 firefox 和 ie9 的调是其中执行的代码,却能的删除全局变量,这在网页脚本中是不会发生的事,当delete 语句删除属性成功时 返回 true,否则返回 false。

    var f = function(){};

    f.prototype = { x:99 };

    var o = new f;

    console.log(o.hasOwnProperty('x')); //false

    console.log(o.x); //99

    delete o.x ;

    console.log(o.x); //99

    var x = 1;

    window.hasOwnProperty('x'); //true

    delete window.x;

    console.log(x); // error,x is not defined ,fire bug, it will not happen in webpage's script codes.

    window.xx = 789; //这样定义的属性是可以删除的

    console.log(xx); //789

    delete window.xx; //true

    console.log(xx); //undeifned ,

    instanceof: 如果obj对象是构造函数Fun的一个实例,则 obj instanceof Fun 返回 true,值得注意的是,instanceof 并不检 查 Fun 函数,而是检查 Fun.prototype,是基于"原形链"的,因此,即使 obj instanceof Fun 返 回 true,obj 也可能不具有 Fun 构造器中定义的属性,因为 Fun 不一定是 obj 的构造器。

    function A(){ this.a = 'a';}

    function Bar(){ this.b= 'b';}

    function C(){ this.c = 'c';}

    var na = new A();

    Bar.prototype = na;

    var bar = new Bar();

    console.log(bar instanceof Bar); //true

    Bar.prototype = new A();

    console.log(bar instanceof Bar); //false  ,instanceof 检测 函数的 prototype, 后一个 new A 不等于前一个 new A,(不相同的对象不会相等)


    C.prototype = na;

    console.log(bar instanceof C); //true

    console.log(na.isPrototypeOf(bar)); //true

    console.log(bar.hasOwnPrototype('c')); //false

    关于instanceof,试考察下面代码: 

        function P(){this.p=11;};

        var pro = new P(); 

        function X() {this.x=88;}  

        function Y() {this.y=99;}  

        Y.prototype =pro; 

        var obj = new Y(); 

        1、对象构造器在哪

        console.log(obj.hasOwnProperty('constructor')); //false

        console.log(obj.constructor); //P

        console.log(obj.__proto__.constructor);//P

        console.log(obj.__proto__.constructor === Y.prototype.constructor); //true

        这说明执行new时,obj.constructor 即 obj.__proto__.constructor 实际是 Y.prototype.constructor 而不是 Y.

        

        2、对象构造器修复

        但是,有一点小问题,考察一下 y 属性:

        console.log(obj.y); // 99

        console.log(obj.__proto__.y); //undefined

        y 属性既然不是来自于“原型链”,那自然是来自于对象构造器,但是 P 函数中并没有定义 y 属性,

        从“类式继承” 形成的“继承链” 看来,P 只是“继承链”的源头,也就是最顶级的 “基类”, obj 对象实例的的构造来源于“子类” y 函数,

        这是 js 对象继承系统中 “模拟类式继承” new 与“原型继承” prototype 之间的一点裂缝,

        很多人执着于修复这个裂缝,于是有了构造器修复的做法.

        默认状态下声明一个函数fun,有fun.prototype.constructor===fun,于是:

        obj.constructor =  Y ; //修复构造器,赋一个constructor属性来覆盖掉继承链上的constructor

        console.log(obj.hasOwnProperty('constructor')); //true

        console.log(obj.constructor); //Y

        console.log(obj.__proto__.constructor); //P

        3、obj instancof Fun 为 true 并不意味着 Fun 一定是 obj 对象的构造器,Fun 可能并不存在于 obj 的继承链中:

        X.prototype = pro;

        console.log(obj instanceof X); //true

        console.log(obj.x);//undefined , X 不是 obj 的构造器

        console.log(obj instanceof Y); //true

        console.log(obj.y);//99

        上面的代码中P函数如果改为  

         function K(){ this.k=66; }

         function P(){this.p=11;};

         P.prototype = new K();  

        那么未修复构造器前,继承链上的构造函数将是K而不是P,也会有:

        console.log(obj instanceof X); //true

        console.log(obj.x);//undefined

        console.log(obj instanceof Y); //true

        console.log(obj.y);//99   

        console.log(obj instanceof K); //true

        console.log(obj.k); //66

      4、Object.create()

      新版本的 ECMAScript 为 Object 对象扩展了一些方法,

      Object.create(pro)可以基于 pro 为原型创建一个对象,其效果相当于  

        var f = function(){};

        f.prototype = pro;

        var obj = new f();

        

        try:

        function P(){this.p=11;}

        function K(){this.k=22;}

        function F(){this.f=33;}

        var pro = new K();

        P.prototype = pro;

        var o= new P(); 

        var obj = Object.create(o);  

        console.log(o,obj); // 都是 {p:11,k:22}

        console.log(obj.constructor); // K

        console.log(obj.__proto__.constructor); //k

        console.log(obj instanceof P); //true

        console.log(obj instanceof K); //true

        console.log(obj instanceof F); //false

        F.prototype = pro;

        console.log(obj instanceof F); //true

      5、Object 与 Function:

      console.log(Function instanceof Object); //true

      console.log(Object instanceof Function); //true

      先有 Function 还是先有 Object ?下面这个现象或许能解释,Object 才是“最顶级”的对象

      console.log(Object.__proto__.__proto__===Function.prototype) ; // false

      console.log(Function.__proto__.__proto__ === Object.prototype); // true

      console.log(Object.prototype.__proto__); // null ,Object 的对象原型已经是女娲级的了

  • 相关阅读:
    Benelux Algorithm Programming Contest 2016 Preliminary K. Translators’ Dinner(思路)
    Benelux Algorithm Programming Contest 2016 Preliminary Target Practice
    Benelux Algorithm Programming Contest 2016 Preliminary I. Rock Band
    Benelux Algorithm Programming Contest 2016 Preliminary A. Block Game
    ICPC Northeastern European Regional Contest 2019 Apprentice Learning Trajectory
    ICPC Northeastern European Regional Contest 2019 Key Storage
    2018 ACM ICPC Asia Regional
    2018 ACM ICPC Asia Regional
    Mybatis入库出现异常后,如何捕捉异常
    优雅停止 SpringBoot 服务,拒绝 kill -9 暴力停止
  • 原文地址:https://www.cnblogs.com/xccjmpc/p/3393366.html
Copyright © 2011-2022 走看看