zoukankan      html  css  js  c++  java
  • JavaScript 原型和原型链 prototype

    • [[prototype]]   原型 

       javaScript 中所有的对象都有一个内置属性[[prototype]], 是对其它对象的引用。那么它默认情况下引用的是什么对象呢

    该属性指向的其构造函数的原型对象    [[prototype]]通过_proto_来访问  或者通过 Object.getPrototypeOf(obj) 来访问

    <script type="text/javascript">
              var obj={a:"apple"};
              var num=new Number(10);
              var ifUp=true;
              console.log("obj.__proto__===Object.prototype:"+(obj.__proto__===Object.prototype));
              console.log("num.__proto__===Number.prototype:"+(num.__proto__===Number.prototype));
              console.log("ifUp.__proto__===Boolean.prototype:"+(ifUp.__proto__===Boolean.prototype));
              
              console.log("obj.__proto__===Object.getPrototypeOf():"+(obj.__proto__===Object.getPrototypeOf(obj)));
              console.log("num.__proto__===Number.getPrototypeOf:"+(num.__proto__===Object.getPrototypeOf(num)));
              console.log("ifUp.__proto__===Boolean.getPrototypeOf:"+(ifUp.__proto__===Object.getPrototypeOf(ifUp)));

    </script>

        函数也是对象,那么函数也有内置的[[prototype]]属性: 那么函数的[[prototype]]指向什么呢'

            <script type="text/javascript">
             function foo()
             {
                 
             }
             
       console.log("foo._proto_:   "+(foo.__proto__==Function.prototype));
       console.log("Object._proto_:   "+(Object._proto_==Function.prototype));
       console.log("Number.__proto__ === Function.prototype    "+(Number.__proto__ === Function.prototype));  // true
       console.log("Boolean.__proto__ === Function.prototype    "+( Boolean.__proto__ === Function.prototype));// true
       console.log("Object.__proto__ === Function.prototype   "+(Object.__proto__ === Function.prototype));  // true
       console.log("String.__proto__ === Function.prototype   "+(String.__proto__ === Function.prototyp)); // true
       console.log("Function.__proto__ === Function.prototype   "+(Function.__proto__ === Function.prototype)); // true
       console.log("Array.__proto__ === Function.prototype   "+(Array.__proto__ === Function.prototype));   // true
       console.log("RegExp.__proto__ === Function.prototype   "+(RegExp.__proto__ === Function.prototype));  // true
       console.log("Error.__proto__ === Function.prototype   "+(Error.__proto__ === Function.prototype));   // true
       console.log("Date.__proto__ === Function.prototype   "+ (Date.__proto__ === Function.prototype)); 
            </script>

    执行结果如下:

     可以看到所有构造器/函数的__proto__都指向Function.prototype,它是一个空函数(Empty function)

     那么,那Function.prototype的__proto__是谁呢? 

      通过上面的截图我们可以看到 Function.prototype._proto_指向的是Object.prototype;

    而:Object.prototype的_proto_指向null   既是 ojbect 位于[[prototype]]原型链的顶端。

    • 原型链

       由于_proto_是任何对象都有的属性,而js中万物皆对象,所有会形成一条_proto_连起来的链条,一直到头,就是Object.prototype._proto_指向null

            <script type="text/javascript">
    var A = function(){};
    var a = new A();
    console.log(a.__proto__); //A {}(即构造器function A 的原型对象)
    console.log(a.__proto__.__proto__); //Object {}(即构造器function Object 的原型对象)
    console.log(a.__proto__.__proto__.__proto__); //null
            </script>

     当查找对象属性的时候,如果对象本身没有找到所需的属性,就会继续访问对象的[[prototype]]链所以JavaScript中所有的对象都可以调用Object的方法:比如:toString()

    如果需要赋值的属性的是对象本事不存在,而在于原型链上会有三种情况产生

        myObject.foo="bar";  //

     1:如果原型链存在foo,并在该属性没有标记为只读的,那么会在myObject上添加一个foo属性,屏蔽原型链上的foo属性

     2:如果原型链上存在foo,并在该属性被标记为只读的,这条语句会被忽略,不会发生屏蔽,如果运行在严格模式下会报错

     3:如果原型链上存在foo并且标记为setter ,会直接的调用这个属性,不会再myObject上创建foo属性

    使用Object.defineProperty(): 可以把属性强制性添加到myObject上,既是第一种情况屏蔽原型链上的属性

    • _proto_ 和 prototype 

     很多同学都搞不清楚它们之之间有什么区别

        _proto_:是所有对象(包括函数)都拥有的内置属性,读取的内置[[prototyope]]内置属性

       prototype:是只有函数才有的

  • 相关阅读:
    浙江省CIO协会钱塘江论坛近日在网易云创沙龙宣布成立
    用Python解析XMind
    Flask写web时cookie的处理
    一篇文章看懂Facebook和新浪微博的智能FEED
    改进网易云音乐的“音乐社交”构想
    移动端爬虫工具与方法介绍
    用供应链管理思路降低教培产品成本
    【网易严选】iOS持续集成打包(Jenkins+fastlane+nginx)
    网易严选的wkwebview测试之路
    linux多进程之间的文件锁
  • 原文地址:https://www.cnblogs.com/cuner/p/12602222.html
Copyright © 2011-2022 走看看