zoukankan      html  css  js  c++  java
  • 深入理解javascript之原型

    理解原型

    原型是一个对象。其它对象能够通过它实现属性继承。

    不论什么一个对象都能够成为继承,全部对象在默认的情况下都有一个原型。由于原型本身也是对象,所以每一个原型自身又有一个原型。

    不论什么一个对象都有一个prototype的属性。记为:__proto__。

    每当我们定义一个对象,其__proto__属性就指向了其prototype。示比例如以下:

     

    var foo = { 
    x: 10, 
    y: 20 
    };
    

    即使我们不指定prototype,该属性也会预留。假设我们有明白指向的话。那么链表就连起来了。

    须要注意的是,prototype自己也有指向,就是最高级的object.prototype。

    示比例如以下:

    var a = { 
    x: 10, 
    calculate: function (z) { 
    return this.x + this.y + z 
    } 
    }; 
    var b = { 
    y: 20, 
    __proto__: a 
    }; 
    
    var c = { 
    y: 30, 
    __proto__: a 
    }; 
    
    // call the inherited method 
    b.calculate(30); // 60
    

    使用原型

    理解了原型的原理之后,怎样使用原型呢?或者说原型有什么作用呢?

    一般的刚開始学习的人。在刚刚学习了主要的javascript语法后,都是通过面向函数来编程的。

    例如以下代码:

    var decimalDigits = 2,
    	tax = 5;
    
    function add(x, y) {
        return x + y;
    }
    
    function subtract(x, y) {
        return x - y;
    }
    
    //alert(add(1, 3));
    

    通过运行各个函数来得到最后的结果。

    可是利用原型,我们能够优化一些我们的代码,使用构造函数

    首先。函数本体中仅仅存放变量:

    var Calculator = function (decimalDigits, tax) {
        this.decimalDigits = decimalDigits;
        this.tax = tax;
    };
    

    其详细的方法通过prototype属性来设置:

    Calculator.prototype = {
        add: function (x, y) {
            return x + y;
        },
    
        subtract: function (x, y) {
            return x - y;
        }
    };
    //alert((new Calculator()).add(1, 3));
    

    这样就能够通过实例化对象后进行对应的函数操作。

    这也是一般的js框架採用的方法。

    原型另一个作用就是用来实现继承

    首先。定义父对象:


    var BaseCalculator = function() {
        this.decimalDigits = 2;
    };
    
    BaseCalculator.prototype = {
        add: function(x, y) {
            return x + y;
        },
        subtract: function(x, y) {
            return x - y;
        }
    };
    

    然后定义子对象。将子对象的原型指向父元素的实例化:

    var Calculator = function () {
        //为每一个实例都声明一个税收数字
        this.tax = 5;
    };
            
    Calculator.prototype = new BaseCalculator();
    

    我们能够看到Calculator的原型是指向到BaseCalculator的一个实例上,目的是让Calculator集成它的add(x,y)和subtract(x,y)这2个function,另一点要说的是,因为它的原型是BaseCalculator的一个实例,所以无论你创建多少个Calculator对象实例,他们的原型指向的都是同一个实例。

    上面的代码。执行以后,我们能够看到由于Calculator的原型是指向BaseCalculator的实例上的,所以能够訪问他的decimalDigits属性值,那假设我不想让Calculator訪问BaseCalculator的构造函数里声明的属性值,那怎么办呢?仅仅须要将Calculator指向BaseCalculator的原型而不是实例即可了。代码例如以下:

    var Calculator = function () {
        this.tax= 5;
    };
    
    Calculator.prototype = BaseCalculator.prototype;
    

    在使用第三方库的时候。有时候他们定义的原型方法不能满足我们的须要,我们就能够自己加入一些方法。代码例如以下:


    //覆盖前面Calculator的add() function 
    Calculator.prototype.add = function (x, y) {
        return x + y + this.tax;
    };
    
    var calc = new Calculator();
    alert(calc.add(1, 1));
    


    原型链

    对象的原型指向对象的父。而父的原型又指向父的父,这样的原型层层的关系。叫做原型链

    在查找一个对象的属性时。javascript会向上遍历原型链,直到找到给定名称的属性为止。当查找到达原型链的顶部,也即是Object.prototype。仍然没有找到指定的属性。就会返回undefined。

    示比例如以下:


    function foo() {
        this.add = function (x, y) {
            return x + y;
        }
    }
    
    foo.prototype.add = function (x, y) {
        return x + y + 10;
    }
    
    Object.prototype.subtract = function (x, y) {
        return x - y;
    }
    
    var f = new foo();
    alert(f.add(1, 2)); //结果是3。而不是13
    alert(f.subtract(1, 2)); //结果是-1
    

    我们能够发现,subtrace是依照向上找的原则,而add则出了意外。原因就是,属性在查找的时候是先查找自身的属性,假设没有再查找原型

    说到Object.prototype,就不得不提它的一个方法。hasOwnProperty。

    它能推断一个对象是否包括自己定义属性而不是原型链上的属性,它是javascript中唯一一个处理属性可是不查找原型链的函数。使用代码例如以下:

    // 改动Object.prototype
    Object.prototype.bar = 1; 
    var foo = {goo: undefined};
    
    foo.bar; // 1
    'bar' in foo; // true
    
    foo.hasOwnProperty('bar'); // false
    foo.hasOwnProperty('goo'); // true
    

    而为了推断prototype对象和某个实例之间的关系,又不得不介绍isPrototyleOf方法,演演示样例如以下:

    alert(Cat.prototype.isPrototypeOf(cat2)); //true




  • 相关阅读:
    要加班了!
    项目经理的职责[转]
    用例图(User Case)
    c# 获取收藏夹目录到树型控件
    活动图(Activity Diagram)
    switch case重构事例[转]
    iframe 语法小结
    CSS入门
    Net中几种不同方式的文件下载
    网页效果集合
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7039266.html
Copyright © 2011-2022 走看看