JavaScript原型和原型链

706 阅读2分钟

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

let arr = []
console.log(arr instanceof Array)     // true 
console.log(typeof arr)              // object , typeof 是无法判断是否是数组的

● 写一个原型链继承的例子

//动物

function Animal(){
    this.eat = function (){
        console.log('adimal eat')
    }
}
// 狗
function Dog(){
    this.bark = function(){
        console.log( 'dog bark')
    }
}

Dog.prototype = new Animal()

//哈士奇

let hashiqi = new Dog()
hashiqi.eat()
hashiqi.bark()

● 描述 new 一个对象的过程

1、创建一个新对象
2this 指向这个新对象
3、执行代码,即对this赋值
4、返回this

知识点

● 构造函数

function Foo(name, age) {
    this.name = name
    this.age = age
    this.class = 'class-1'
    // return this      默认有这一行
}


let f = new Foo('zhangsan', 20)
// let f1 = new Foo('list', 22)          创建多个对象




● 构造函数 - 扩展

 let a = {} 其实是  let a = new Object() 的语法糖

 let a = [] 其实是 var a = new Array() 的语法糖

 function Foo() {...} 其实是 var Foo =  new Function(...)
    
 建议使用 let a = {} 这种字面量方式创建
                                                  

 使用 instanceof 判断一个函数是否是一个变量的构造函数

● 原型规则和示例

1、所有的引用类型(数组、对象、函数) , 都具有对象特性,即可自由扩展属性(除了"null"以外)
let obj = {}; obj.a =100;
let arr = []; arr.a = 100;
function fn(){}
fn.a = 100;
2、所有的引用类型(数组、对象、函数),都有一个__protp__(隐式原型,prototype缩写)属性,属性值是一个普通的对象
console.log(obj.__proto__)
console.log(arr.__proto__)
console.log(fn.__proto__)
3、所有的函数,都有一个 prototype(显式原型) 属性 , 属性值也是一个普通的对象
console.log(fn.prototype)
4、所有的引用类型(数组、对象、函数) , __proto__属性值指向它的构造函数的"prototype" 属性值
console.log(obj.__proto__ === Object.prototype)
5、当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的 proto(即它的构造函数的prototype)中寻找
function Foo(name,age){
    this.name = name
}
Foo.prototype.alertNmae = function (){
    alert(this.name)
}

let f = new Foo('张三')       // 实例的出的f 的 __proto__(隐式原型) 会指向 它的构造函数的prototype(显示原型) 就是Foo的prototype
f.printName = function(){
    console.log(this.name)
}
f.printName() //张三            
f.alertNmae() //张三

console.log(f.__proto__ === Foo.prototype);  // true

● 原型链

1568461844359


● instanceof

// f instanceof Foo 的判断逻辑是:
// f 的 __proto__ 一层一层 往上, 能否对应到Foo.prototype
// 再试着判断 f instanceof Object 

console.log(f instanceof Object)  //true

小栗子

function Elem(id) {
    this.elem = document.getElementById(id)
}

Elem.prototype.html = function (val) {
    let elem = this.elem
    if (val) {
        elem.innerHTML = val
        return this //返回 自己本身 实现链式操作
    } else {
        return elem.innerHTML
    }
}
Elem.prototype.on = function(type,fn){
    let elem = this.elem
    elem.addEventListener(type,fn)
    return this
}


let div1 = new Elem('div1')

console.log(div1.html('<p>是吗</p>').on('click',function(){
    alert('111')
}))