zoukankan      html  css  js  c++  java
  • js——prototype、__proto__、constructor

                                        Object                                   

    1. Object是一个函数(typeof Object;//function)。Object构造器创建了一个对象包装器

    1 //Object{}
    2 var o = new Object(null);
    3 //Object{}
    4 var o = new Object(defined);
    5 //Number
    6 var o = new Object(1);
    7 //Boolean
    8 var o = new Object(true);
    View Code

    2. Object.prototype属性是Object的原型对象

    3. js中几乎所有objects都是Object的实例,一个object会继承Object.prototype的所有属性,这些属性也可能被屏蔽。

    4. JavaScript没有子类对象,原型用于为某些表现为对象的函数创建一个“基类”对象 

                                       Constructor                                   

    Foo函数在声明时,Foo.prototype有一个默认属性.constructor,这个属性默认指向Foo

    它不表示“由。。。构造”!

    var a = new Foo();
    a.constructor === Foo;//true
    //a.__proto__ == Foo.prototype
    //a.constructor被委托给Foo.prototype
    //Foo.prototype.constructor默认为Foo

    对象的constructor默认指向一个函数,这个函数可以通过对象的.prototype引用

                                        __proto__                                   

    1. __proto__属性是个可访问的属性,它可以用来访问[[Prototype]]

    2. __proto__的使用不被鼓励。它一开始并没有被包含在EcmaScript中,但是浏览器却一定要实现它。为了保证兼容性,未来将会在ECMAScript2015中规范并支持。

    更推荐使用Object.getPrototypeOf/setPrototypeOf

    3.__proto__ 的实现,get和set:

    1 Object.defineProperty(Object.prototype, "__proto__", {
    2     get: function(){
    3         return Object.getPrototyperOf(this);
    4     },
    5     set: function(o){
    6         Object.setPrototypeOf(this, o);
    7         return o;
    8     }
    9 });
    View Code

                                        prototype                                   

    1. 函数中有prototype对象,非函数没有prototype对象

    2. 函数的prototype在new的时候起作用。让new func()出来的对象的__proto__指向func.prototype

    3. 那没有自己设置prototype的函数的prototype是什么值?

    function a(){}
    //a.__proto__ -->function(){[native code]}
    //a.constructor -->function Function{[native code]}
    //a.prototype.__proto__ -->Object.prototype
    //a.prototype.constructor --> a

                                        继承和原型链                                   

    1. 继承:js只有一个构造器objects。每个object有一个私有属性[[Prototype]],它指向另一个对象,称为它的prototype对象。

    2. prototype对象也有它的prototype对象,最后达到null。null没有prototype对象,因此它是原型链的最后节点

    3. 原型链:当想要访问一个对象属性时,它从当前对象开始一直沿着它的原型向上访问,直到null

    4. 基于原型链的继承

    • 继承属性 
    myObject.foo = "bar";

            myObject有foo属性,修改foo的值(屏蔽原型链上的) 

    myObject无foo属性,沿myObject原型链向上查找,且原型链上有foo属性

      • 可写:在myObject添加foo属性(屏蔽原型链上的)
      • 不可写:语句被忽略/报错(严格模式)
      • 是setter:不改变 
    • 继承方法

            与继承属性类似

    5. 创建对象的不同方法及原型链

     1 //1. 普通语法
     2 //o --> Object.prototype
     3 var o = {a:1};
     4 //o --> Array.prototype -->Object.prototype 
     5 var o = [1, 2]; 
     6 //f --> Function.prototype -->Object.prototype
     7 function f(){
     8     return 2;
     9 }
    10 
    11 //2. new
    12 function Graph(){
    13     this.vertices = [];
    14     this.edges = [];
    15 }
    16 Graph.prototype = {
    17     addVertex: function(v){
    18         this.vertices.push(v);
    19     }
    20 };
    21 //g-->Graph.prototype--> Object.prototype
    22 var g = new Graph();
    23 
    24 //3. Object.create
    25 //a-->Object.prototype
    26 var a = {a:1};
    27 //b-->a-->Object.prototype
    28 var b = Object.create(a);
    29 
    30 //4. class关键字
    View Code

     6. 性能

    • 在原型链上查找属性比较耗时,试图访问不存在的属性时会遍历整个原型链
    • 遍历对象的属性时,原型链上的每个可枚举属性都会被枚举出来
    • hasOwnProperty是js中唯一一个只涉及对象自身属性而不会遍历原型链的方法
    • 仅判断值是否为undefined不足以检测一个属性是否存在,它可能存在而值恰好为undefined
    var a = {
        b: undefined
    };
    a.b;//undefined

    7. 不好的实践:扩展原生对象的原型 

             prototype和getPrototypeOf(__proto__)         

    在函数中有一个属性prototype,它是和new操作符相关的特殊属性

    在内存中创建一个对象,在运行函数前,会把[[prototype]]链接到函数的prototype

    var o = new Foo();

     等价于:

    var o = new Object();
    o.[[prototype]] = Foo.prototype;
    Foo.call(o);
    //返回o

    总的来说:

    prototype is for types, while Object.getPrototypeOf() is the same for instance

    在prototype中定义的属性可以被new出来的对象共享

            我的总结吧~         

    1. __proto__是每个对象都有的属性,用于访问对象的原型,形成原型链路

    2. prototype是函数才有的属性,它在new的时候起作用。

        var a = new A();//使得a.__proto__ = A.prototype

    3. 为什么要在函数中加一个prototyp属性?(个人理解)

       如果不加的话,只能有两种情况:a.__proto__ = A 或者a.__proto__ = A.__proto__

       A是一个函数,而a希望是一个对象,这样会使得一个对象有函数的属性,这就不太合理了吧。 

    4. 与C++类的简单比较

    C++ js
    class A(){
      public:
          A(){}
    }
    function A(){
    }
    A.prototype={
    }
    • C++:定义一个类A,A中包括了一个构造函数A(),并封封装了需要的属性
    • js:定义一个function A(){},A有prototype属性,A.prototype中定义需要的属性
    • 所以,这两个的构造函数和封装属性的对象有点反过来的意思吧 

    5. constructor

    function A(){}//定义一个函数
    A.prototype.constructor == A;//true

    下面图的关联关系是从chrome运行结果整理出来的

    参考:

    1. 《你不知道的javascript》上卷

    2. MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

    最后,

    不企图只看一篇文章然后懂得所有,还是要多翻几篇文章吧。

  • 相关阅读:
    CDN网络(二)之配置和优化CDN核心缓存软件--squid
    CDN网络(一)之典型的CND架构与HTTP协议的缓存控制
    http+mysql结合keepalived做热备
    网络存储(四)之ISCSI的进阶
    Nginx系列3之Nginx+tomcat
    Nginx系列2之Nginx+php
    Nginx系列1之部分模块详解
    网络存储(三)之ISCSI搭建的入门
    网络存储(二)之ISCSI原理
    Testing
  • 原文地址:https://www.cnblogs.com/coolqiyu/p/7128748.html
Copyright © 2011-2022 走看看