zoukankan      html  css  js  c++  java
  • JavaScript原型学习

    原型:
      原型是一个对象,任何对象默认都有一个原型,唯一例外的是默认的对象原型,它在原型链的顶端。

    对象:
      对象是无需键值对的集合。
      在JavaScript中,如果不是一个主数据类型(undefined/null/boolean/number/string)就是一个对象。
      一个对象的原型,被对象内部的[[prototype]]属性(propety)所持有。

    原型访问器:
      ①ECMA标准对象原型访问器:Object.getPrototype(obj)【FireFox、Chrome支持】
      ②非标准对象原型访问器:__proto__ 【除了IE都支持】
      ③当上述2种不起作用时,可通过对象的构造函数找到它的原型:obj.constructor.prototype【所有浏览器支持】

    var a = {};
    
    Object.getPrototypeOf(a);     //[object Object]
    a.__proto__;    //[object Object]
    a.constructor.prototype;    //[object Object]

      当尝试获取一个主数据类型的原型时,它会被强行转换为一个对象:

    false.__proto__ === Boolean(false).__proto__;  //true

     在继承中使用原型:
      原型的魅力在于多个实例共用一个通用原型。
      让一个实例对象 继承一个已经存在的对象(如Array)的功能:

    var a = {};
    a.__proto__ = Array.prototype;    //为a对象的原型 赋值 Array的原型属性
    a.length;    // 0

       原型对象【某个对象(如上述a)的原型引用的对象(如Array)】的属性【如Array.prototype】一旦定义,就可以被多个引用它的实例所继承。

     原型的继承也是构造函数之所以存在的原因:
      构造函数是一种方便的跨浏览器机制,允许在创建实例时 为实例提供一个通用的原型。

    constructor.prototype属性
      JavaScript没有区别构造函数(constructor)和其他函数,故每个函数都有一个原型属性(prototype),不是函数则没有。

    Math.max.prototype;    //[object Object]
    
    var a = function(name){
        this.name = name;
    }
    
    a.prototype;    //[object Object]
    
    Math.prototype;    // null

      函数a的原型属性(prototype propety)是一个对象,当函数a创建实例时,函数的原型属性会作为原型 赋值给所有对象实例。
      即,所有实例的原型(如oIns.__proto__) 引用的都是函数的原型属性(如a.prototype)。

    //创建一个函数b
    var b = function(){ var one; }
    //使用b创建一个对象实例c
    var c = new b();
    //查看b 和c的构造函数
    b.constructor;  // function Function() { [native code]}
    b.constructor==Function.constructor; //true
    c.constructor; //实例c的构造函数 即 b function(){ var one; }
    c.constructor==b //true
    
    //b是一个函数,查看b的原型如下
    b.constructor.prototype // function (){}
    b.__proto__  //function (){}
    
    //b是一个函数,由于javascript没有在构造函数constructor和函数function之间做区分,所以函数像constructor一样,
    //有一个原型属性,这和函数的原型(b.__proto__ 或者b.construtor.prototype)是不一样的
    b.prototype //[object Object]   函数b的原型属性
    
    b.prototype==b.constructor.prototype //fasle
    b.prototype==b.__proto__  //false
    b.__proto__==b.constructor.prototype //true
    
    //c是一个由b创建的对象实例,查看c的原型如下
    c.constructor.prototype //[object Object] 这是对象的原型
    c.__proto__ //[object Object] 这是对象的原型
    c.constructor.prototype==b.constructor.prototype;  //false  c的原型和b的原型比较
    c.constructor.prototype==b.prototype;  //true c的原型和b的原型属性比较
    
    //为函数b的原型属性添加一个属性max
    b.prototype.max = 3
    //实例c也有了一个属性max
    c.max  //3
    上面的例子中,对象实例c的原型和函数的b的原型属性是一样的,如果改变b的原型属性,则对象实例c
    的原型也会改变

    一个函数的原型属性(function`s prototype propety) 与其原型(prototype)没有关系:

    var a = function(name){
        this.name = name;
    }
    a.prototype == a.__proto__;    //false
    a.__proto__ == Function.prototype;    //true

    改变原型引用的原型属性所在的函数,原型所在的实例会随着改变:

    var A = function(name) {
        this.name = name;
     }   
    var B = new A('alpha');
    B.name; //'alpha'   
     A.prototype.x = 23;   //引用的原型属性所在的A添加属性x,原型所在的实例B会随着添加引用x
    B.x; //23

    instance of:判断原型

    var A = function() {}   
    var B = new A();
    
    B.__proto__ == A.prototype;
    B instanceof A; //true;   
    B.__proto__ = Function.prototype;
    B instanceof A; //false

     

    原型的应用:实现复制字符串的方法

    String.prototype.times = function(count) {
        return count < 1 ? '' : new Array(count + 1).join(this); //创建一个数组,将调用方法的字符串作为分隔符,转换为字符串
     }
     
    "hello!".times(3); //"hello!hello!hello!"; 复制3次
     
    "please...".times(6);//"please...please...please...please...please...please..."; 复制6次

    继承原理,原型链:
      每个对象都有一个原型,对象的原型指向父,而父的原型指向父的父,通常把通过原型层层链接起来的关系 称为原型链。
      原型链的末端一般是 默认的对象原型。

    a.__proto__ = b;
    b.__proto__ = c;
    c.__proto__ = {}; //default object
    {}.__proto__.__proto__; //null

      原型的继承机制 是发生在内部且隐式的,当要获取一个对象的属性时,JavaScript会在原型链中查找该属性,不存在则返回undefined

     


    译文:blog.jobbole.com/9648/#comment-15216
    英文原文:http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/

  • 相关阅读:
    1020. Tree Traversals
    1001. A+B Format
    centos 各类无线网卡编译
    vim 详细配置 超全
    深夜复习strcpy函数原型竟然暗藏着这么多玄机
    第一篇博客
    strcat函数使用中出现的问题
    strcpy与strncpy工作方式及其区别
    strcpy与面试官
    linux下多线程编程
  • 原文地址:https://www.cnblogs.com/slowsoul/p/3102618.html
Copyright © 2011-2022 走看看