原型和原型链

一、从题目入手 

1. 如何准确判断一个变量是数组类型

变量 instanceof Array

无法用 typeof 判断,Object,Array都是Object;只有函数的 typeof 是function

2. 写一个原型链继承的例子

封装一个DOM查询

//定义构造函数
function
Elem(id){ this.Elem = document.getElementById(id) } //添加属性 Elem.prototype.html = function(val){ var elem = this.Elem if(val){ elem.innerHTML = val return this //链式操作 } } Elem.prototype.on = function(type,fn){ var elem = this.Elem elem.addEventListener(type,fn) return this //链式操作 } //创建实例 var div1 = new Elem('div1') div1.html('<p>这是一个原型链实例</p>').on('click',function(){
alert('ok')
}) //链式操作的应用

3. 描述 new 一个对象的过程

  • 创建一个新对象
  • this指向这个新对象
  • 执行代码,即对this赋值
  • 返回this

4. zepto(或其他框架)源码中如何使用原型链

http://www.kancloud.cn/wangfupeng/zepto-design-srouce/173680 

初始化zepto的过程

var Zepto = (function(){
    var $,
        zepto = {}
    
    // ...省略N行代码...

    zepto.Z = function(dom, selector) {
      dom = dom || []
      dom.__proto__ = $.fn
      dom.selector = selector || ''
      return dom
    }
    
    zepto.init = function(selector, context) {
        var dom
        
        // 针对参数情况,分别对dom赋值
        
        // 最终调用 zepto.Z 返回的数据
        return zepto.Z(dom, selector)
    }
    
    $ = function(selector, context){
        return zepto.init(selector, context)
    }
    
    $.fn = {
        // 里面有若干个工具函数
    }
    
    // ...省略N行代码...
    
    return $
})()

window.Zepto = Zepto
window.$ === undefined && (window.$ = Zepto)

二、知识点 

1. 构造函数

function Foo(name,age){
  this.name = name;
  this.age = age;
  this.class = 'class-1';
  //return this  //默认有这一行
}
var f = new Foo('jack',20);
//var f2 = new Foo('jenny',22);//创建多个对象

执行 new 会将 this 变成空对象,通过构造函数赋值后,返回 this 的值赋给 实例变量(f)

2. 构造函数 - 扩展

  • var a = {} 其实是 var a = new Object() 的语法糖
  • var a = [] 其实是 var a = new Array() 的语法糖
  • function Foo(){...} 其实是 var Foo = new Function(...)
  • 使用instanceof判断一个函数是否是一个变量的构造函数

3. 原型规则和示例

  • 所有引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除“null”以外)。
  • 所有引用类型(数组、对象、函数),都有一个__proto__属性.
  • 所有函数,都有一个prototype属性,属性值是一个普通的对象。
  • 所有引用类型(数组、对象、函数),__proto__属性值指向它的构造函数的“prototype”属性值。
var arr = [];
console.log(arr.__proto__===Array.prototype)//true
  • 当试图得到一个引用类型的某个属性时,如果这个变量本身没有这个属性,那么会去__proto__(即它的构造函数的prototype)中寻找
//构造函数
function Foo(name,age){
  this.name = name
}
Foo.prototype.alertName = function(){
  alert(this.name)
}
//创建实例
var f = new Foo('jack')
f.printName = function(){
  alert(this.name)
}
//测试
f.printName()//jack
f.alertName()//jack

利用该特性可随意向数组添加自定义方法

var arr = [1,2,3]
arr.__proto__.sum = function(){
  return 1+2+3
} 
alert(arr.sum());

4. 原型链

5. instanceof

f instanceof Foo/Object 的判断逻辑是:

f 的 __proto__ 一层一层往上找,能否对应到Foo.prototype/Object.prototype

原文地址:https://www.cnblogs.com/embrace-ly/p/10797697.html