美文网首页
原型和原型链

原型和原型链

作者: 安好每个你 | 来源:发表于2017-10-26 00:08 被阅读12次

构造函数

//首字母是大写的函数基本都是构造函数
function Foo(name, age) {
    this.name = name
    this.age = age
    this.class = 'class-1'
    //return this      //默认有这一行,就是如果不添加return this,也会默认返回this
}
var f = new Foo('zhangsan', 20)

步骤:1.传入参数 2.this变成空对象 3.return this

构造函数-扩展

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

判断一个变量是否为“数组”:变量instanceof Array

原型规则和示例

1.所有的引用类型(数组、函数、对象),都具有对象特性,即可自由扩展属性(除了“null”以外)

var obj = {}; obj.a = 100;
var arr = []; arr.a = 100;
function fn () {}; fn.a = 100;
自由扩展属性就是都可以添加a属性,自然也可以添加b,c等其他属性

2.所有的引用类型(数组、对象、函数,不包括null),都有一个proto属性,属性值是一个普通的对象

__proto__ : 隐式原型
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);

3.所有函数都有一个prototype属性,属性值也是一个普通对象

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.alertName = function () {
    alert(this.name)
}
//创建示例
var f = new Foo('zhangsan')
f.printName = function() {
    console.log(this.name)
}
//测试
f.printName()
f.alertName()
//f本身没有alertName属性,那么f会去f的隐式原型中寻找,
相当于去f的构造函数Foo的prototype中寻找,Foo的显式原型已经扩展好了alertName属性

//this永远指向f自身,所以两个结果打印出的都是'zhangsan'

循环对象自身的属性

var item
for (item in f) {
    //判断是否是来自f自身的属性
    if (f.hasOwnProperty(item)) {
        console.log(item)
    }
}

原型链

f.toString()       //要去f.__proto__.__proto__中寻找
2107997750.jpg

instanceof

instanceof用于判断 引用类型 属于哪个 构造函数 的方法
f instanceof Foo 的判断逻辑是:
f 的 proto 一层层往上,能否对应到 Foo.prototype
再试着判断 f instanceof Object

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

instanceof判断

var arr = []
arr instanceof Array        //true
typeof arr             //object,typeof是无法判断是否是数组的

写一个原型链继承的例子

//动物
function Animal() {
    this.eat = function () {
        console.log('animal eat')
    } 
}
//狗
function Dog() {
    this.bark = function() {
         console.log('dog bark')
    }
}
Dog.prototype = new Animal()         //把Dog的显式原型赋值成一个对象
var hashiqi = new Dog()

描述new一个对象的过程

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

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

写一个封装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         //链式操作
    } else {
         return elem.innerHTML
    }
}
Elem.prototype.on = function (type, fn) {
    var elem = this.elem           //获取元素
    elem.addEventListener(type, fn)
    return this
}
var div1 = new Elem('question-header')
//console.log('div1.html()')
div1.html('<p>hello imooc</p>')
div1.on('click', function() {
    alert('clicked')
})
//链式操作
//在扩展属性时,结尾返回return this,就可以有链式操作
div1.html('<p>hello imooc</p>').on('click', function() {alert('clicked')
}).html('<p>javascript</p>')

相关文章

网友评论

      本文标题:原型和原型链

      本文链接:https://www.haomeiwen.com/subject/lvfqpxtx.html