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 的对象原型已经是女娲级的了

  • 相关阅读:
    Jabref安装及使用教程
    均方误差与均方根误差
    费马大定理
    JabRef设置
    申请内存时底层发生了什么?
    什么是Pipeline?
    基于三维点云场景的语义及实例分割
    华为 MateView 系列显示器新品
    C#-WinForm跨线程修改UI界面
    C# 代码生成二维码方法及代码示例(QRCoder)
  • 原文地址:https://www.cnblogs.com/xccjmpc/p/3393366.html
Copyright © 2011-2022 走看看