Skip to content

Latest commit

 

History

History
73 lines (56 loc) · 2.51 KB

2017-12-07__设计模式.md

File metadata and controls

73 lines (56 loc) · 2.51 KB

笔记

《javascript设计模式与开发实践》

js的原型继承

原型编程的基本规则

· 所有的数据都是对象
· 要得到一个对象,不是通过实例化类(new 并不是实例化类,而是调用构造器),而是找到一个对象作为原型并克隆它
· 对象会记住他的原型
· 如果对象无法响应某个请求,会把请求委托给自己的原型

根对象 Object.prototype

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

克隆对象的操作过程理解

在 Chrome 和 Firefox 等向外暴露了对象__proto__属性的浏览器下,我们可以通过下面这段代 码来理解 new 运算的过程

function Person( name ){ 
    this.name = name;
};

Person.prototype.getName = function(){ 
    return this.name;
};

var objectFactory = function(){
    var obj = new Object(), // 从 Object.prototype 上克隆一个空的对象
        Constructor = [].shift.call( arguments ); // 取得外部传入的构造器,此例是 Person
    obj.__proto__ = Constructor.prototype; // 指向正确的原型
    var ret = Constructor.apply( obj, arguments );  // 借用外部传入的构造器给 obj 设置属性
    return typeof ret === 'object' ? ret : obj;   // 确保构造器总是会返回一个对象
};

var a = objectFactory( Person, 'sven' );
console.log( a.name ); // 输出:sven
console.log( a.getName() ); // 输出:sven
console.log( Object.getPrototypeOf( a ) === Person.prototype ); // 输出:true

bind call apply

Function.prototype.bind的模拟实现

Function.prototype.bind = function () {
    var self = this; // 保存原函数
        context = [].shift.call(arguments); // 获取绑定的this上下文
        args = [].slice.call(arguments); // 剩余的参数转为数组
    return function () { // 返回一个新函数
        return self.apply(context, [].concat.call(args, [].slice.call(arguments)));
        // 执行新的函数的时候,会把之前传入的 context 当作新函数体内的 this
        // 并且组合两次分别传入的参数,作为新函数的参数
    }
}

var obj = { name: 'sven' };
var func = function( a, b, c, d ){
    alert ( this.name ); // 输出:sven
    alert ( [ a, b, c, d ] ) // 输出:[ 1, 2, 3, 4 ]
}.bind( obj, 1, 2 ); 
func( 3, 4 );