• JavaScript设计模拟


    原型模式和基于原型继承的JavaScript对象系统

    使用克隆的原型模式
    var Plane = function(){ this.blood = 100; this.attackLevel = 1;     this.defenseLevel = 1;
    };
    var plane = new Plane(); plane.blood = 500; plane.attackLevel = 10; plane.defenseLevel = 7;
    var clonePlane = Object.create( plane );
    console.log( clonePlane ); // 输出:Object {blood: 500, attackLevel: 10, defenseLevel: 7}
    在不支持 Object.create 方法的浏览器中,则可以使用以下代码:
    Object.create = Object.create || function( obj ){ var F = function(){};
    F.prototype = obj;
    return new F(); }    

    JavaScript中的原型继承

    JavaScript 也同样遵守这些原型编程的基本规则。

     所有的数据都是对象。
     要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它。  对象会记住它的原型。
     如果对象无法响应某个请求,它会把这个请求委托给它自己的原型。

    下面我们来分别讨论 JavaScript 是如何在这些规则的基础上来构建它的对象系统的。

    1. 所有的数据都是对象

    JavaScript 在设计的时候,模仿 Java 引入了两套类型机制:基本类型和对象类型。基本类型 包括 undefined、number、boolean、string、function、object。从现在看来,这并不是一个好的 想法。

    按照 JavaScript 设计者的本意,除了 undefined 之外,一切都应是对象。

    事实上,JavaScript 中的根对象是 Object.prototype 对象。Object.prototype 对象是一个空的 对象。我们在 JavaScript 遇到的每个对象,实际上都是从 Object.prototype 对象克隆而来的, Object.prototype 对象就是它们的原型。比如下面的 obj1 对象和 obj2 对象:

    var obj1 = new Object(); var obj2 = {};

    可以利用 ECMAScript 5 提供的 Object.getPrototypeOf 来查看这两个对象的原型:

    console.log( Object.getPrototypeOf( obj1 ) === Object.prototype ); // 输出:true

    console.log( Object.getPrototypeOf( obj2 ) === Object.prototype ); // 输出:true

    2. 要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它

    3. 对象会记住它的原型

    JavaScript 给对象提供了一个名为__proto__的隐藏属性,某个对象的__proto__属性默认会指 向它的构造器的原型对象,

    即{Constructor}.prototype。在一些浏览器中,__proto__被公开出来, 我们可以在 Chrome 或者 Firefox 上用这段代码来验证:

    var a = new Object();
    console.log ( a.__proto__=== Object.prototype ); // 输出:true

    4. 如果对象无法响应某个请求,它会把这个请求委托给它的构造器的原型

    这条规则即是原型继承的精髓所在。从对 Io 语言的学习中,我们已经了解到,当一个对象 无法响应某个请求的时候,它会顺着原型链把请求传递下去,直到遇到一个可以处理该请求的对 象为止。

    this的指向

    除去不常用的 with 和 eval 的情况,具体到实际应用中,this 的指向大致可以分为以下 4 种。

     作为对象的方法调用。
     作为普通函数调用。
     构造器调用。
     Function.prototype.call 或 Function.prototype.apply 调用。

    1. 作为对象的方法调用 当函数作为对象的方法被调用时,this 指向该对象:

    var obj = {

      a: 1,

      getA: function(){
        alert ( this === obj ); // 输出:true alert ( this.a ); // 输出: 1

      }

    };

    obj.getA();

    2. 作为普通函数调用 当函数不作为对象的属性被调用时,也就是我们常说的普通函数方式,此时的 this 总是向全局对象。在浏览器的 JavaScript 里,这个全局对象是 window 对象。

    window.name = 'globalName';
    var getName = function(){ 
        return this.name;
    };
    console.log( getName() );// 输出:globalName
    或者:
    window.name = 'globalName';
    var myObject = { 
        name: 'sven',
        getName: function(){ 
            return this.name;
        } 
    };
     var getName = myObject.getName;
     console.log( getName() ); // globalName 

    call和apply的用途

    1. 改变 this 指向

    2. Function.prototype.bind

    Function.prototype.bind = function( context ){ 
        var self = this; // 保存原函数
        return function(){ 
            return self.apply( context, arguments );// 返回一个新的函数
          // 执行新的函数的时候,会把之前传入的 context 
        // 当作新函数体内的 this
    } };
    var obj = {
        name: 'sven'
    };
    var func = function(){ 
        alert ( this.name );
    }.bind( obj); 
    func();// 输出:sven   

    3. 借用其他对象的方法-这个对象至少还要满足:

     对象本身要可以存取属性;

     对象的 length 属性可读写。

    var a = {};
    Array.prototype.push.call( a, 'first' );
    alert ( a.length ); // 输出:
    alert ( a[ 0 ] ); // first

    u

  • 相关阅读:
    《人月神话》阅读笔记3
    第十五周总结
    《人月神话》阅读笔记2
    对正在使用的输入法评价
    课堂练习(找水王问题)
    第二阶段冲刺第十天
    第二阶段冲刺第九天
    第二阶段冲刺第八天
    第二阶段冲刺第七天
    openwrt U盘启动
  • 原文地址:https://www.cnblogs.com/chenzxl/p/12023299.html
Copyright © 2020-2023  润新知