• 关于原型和原型链的学习


    渐进增强过程:

    -> 刚学习js的时候,一般都是用如下的方式来写代码:

    var  decimalDigits = 2,tax = 5;

    function add(x, y){ return x + y;}

    function subtract(x, y){return x - y;}

    -> 学习了原型后,我们可以使用如下方式来美化代码:

    var Calculator = function(decimalDigits, tax){

      this.decimalDigits = decimalDigits;

      this.tax = tax;

    }

    然后,通过Calculator对象的prototype属性赋值对象字面量来设定Calculator对象的原型。

    Calculator.prototype = {

      add: function(x, y){return  x + y;}, 

      subtract: function(x, y){return x - y;}

    }

    这样,就可以new Calculator对象后,调用add等方法了。

    -> 第二种方式,在赋值原型prototype的时候使用function立即执行的表达式来赋值,即如下格式:

    Calculator.prototype = function(){}();

    它的好处就是封装私有的function,通过return的形式暴露出简单的使用名称,以达到public/private的效果,修改代码如下:

    Calculator.prototype = fucntion(){

      var add = function(x, y){

        return x + y;

      },

      subtract = function(x, y){

        return x - y;

      }

      return {

        add: add,

        subtract: subtract

      }

    }();

    ->再来一点,分步声明:

    上述使用原型的时候,有一个限制就是一次性设置了原型对象,我们再来说一下如何分开来设置原型的每个属性。

    var BaseCalculator = function(){

      //为每一个实例都声明一个小数位数

      this.decimalDigits = 2;

    }

    //使用原型给BaseCalculator扩展2个对象方法

    BaseCalculator.prototype.add = function(x, y){

      return x + y;

    }

    BaseCalculator.prototype.subtract = function(x, y){

      return x - y ;

    }

    var Calcalculator = function(){

      //为每个实例都声明一个税收数字

      this.tax = 5;

    }

    Calculator.prototype  = new BaseCalculator();

    至此,Calculator的原型是指向到 BaseCalculator的一个实例上的,目的是让Calculator集成它add(x,y)和subtract(x,y)这2个function,还是有一点是:由于它的原型是BaseCalculator的一个实例,所以不管你创建多少个Calculator对象实例,他们的原型指向的都是同一个实例。

    var calc = new Calculator();

    calc.add(1,1);

    calc.decimalDigits;

    如果我们不想让Calculator访问BaseCalculator的构造函数里声明的属性值:

    var Calculator = function(){

       this.tax = 5;

    }

    Calculator.prototype = BaseCalculator.prototype;

    通过将BaseCalculator的原型赋值给Calculator的原型,这样你在Calculator的实例上 就访问不到那个decimalDigits值了。

    -> 重写原型 

    在使用第三方JS类库的时候,往往有时候他们定义的原型方法不能满足我们的需求,但是又离不开这个类库,所以这时候我们就需要重写他们 的原型中的一个或者多个属性或function,我们可以通过继续声明的同样的add代码形式来达到覆盖重写前面add的功能,代码如下:

    //覆盖前面的Calculator的add function

    Calculator.prototype.add = function(x, y){

      return x + y + this.tax;

    }

    需要注意一点:那就是重写的代码需要放在最后,这样才能覆盖前面的代码。

    -> hasOwnProperty函数

    hasOwnProperty是Object.prototype的一个方法,它能判断一个对象是否包含自定义属性而不是原型链上的属性,因为hasOwnProperty是JavaScript中唯一一个处理属性但是不查找原型链的函数。

    但是有个恶心的地方时:JS不会保护hasOwnProperty被非法占用,因此如果一个对象碰巧存在这个属性,就需要使用外部的hasOwnProperty函数来获取正确的结果。

    var foo = {

      hasOwnProperty: function(){

        return false;

      },

      bar: 'Here be dragons'

    };

    foo.hasOwnProperty('bar');//总是返回false

    //使用{}对象的hasOwnProperty并将其上下为设置为foo

    {}.hasOwnProperty.call(foo,'bar');//true

    当检查对象上某个属性是否存在时,hasOwnProperty是唯一可用的方法。同时在使用for in loop遍历对象时,推荐总是使用hasOwnProperty方法,这将会避免原型对象扩展带来的干扰。

    Object.prototype.bar = 1;

    var foo = {moo:2}

    for(var i in foo){

      console.log(i);//输出两个属性:bar和moo

    }

    我们没办法改变for in语句的行为,所以想过滤结果只能使用hasOwnProperty方法,代码如下:

    for(var i in foo){

      foo.hasOwnProperty(i) && console.log(i);

    }

  • 相关阅读:
    [转载] 论C#与Java之异同
    MultiThread WebRequest : Timeout
    FCL(2) :: CollectionBase & Collection
    msn 81000306 无法登录,解决方法
    接口一个被我忽略的地方接口重定向技术
    <<Clr Via C#>> Key Points (1) (46章)
    FCL(3):: ArrayList & List (1)
    TCP保活机制
    子网划分
    freopen函数
  • 原文地址:https://www.cnblogs.com/xuqiuyu/p/5798781.html
Copyright © 2020-2023  润新知