原型、原型链、实现继承

2018-06-17  本文已影响0人  Camilia_yang

一、全局变量

window是全局变量(浏览器的叫法),EMCAScript规定全局变量是global。
window 是一个哈希表,有很多属性。
window的属性就是全局变量。

全局变量分成两种:
1.一种是 ECMAScript 规定的

二、简单类型和对象的区别

举例:1 与 new Number(1)
1是基本数据类型1(数值),存在stack(栈)内存里;
new Number(1)是通过New操作符创建了一个数值对象,存在Heap内存里;

为什么(1).toString() 可以输出数值1的字符串形式并且不报错?
因为在执行"(1).toString()" 时,其实是先把数据1包装成了一个temp对象(字符串对象),然后调用其原型链中的toString属性,在一行代码执行后,这个临时对象就被摧毁。

三、原型

为了节省内存空间,所以有了原型(即共用属性)
所有对象的原型:Object.prototype
每一个对象的 proto 存储这个「公用属性组成的对象」的地址。

重要公式:
var 对象 = new 构造函数()
对象.proto === 构造函数.prototype

四、原型链与继承

举例,
a=new Array()
a.push() //实例属性,因为a的类是Array,push方法是从Array中得到的。不是继承。
a.valueOf() //“继承”了Object的属性

继承的实质是:两次的原型搜索。

五、如何实现继承

简单来说,能造出一个【对象】的东西,就叫做“类”。
比如,下面的Human函数就是一个类,

写一个类——Human
给Human类一个共有属性
再写一个更具体的类,“Human”里面的“Man“
Man类
现在,我们来实现”继承“,让Man的_proto_指向Human.prototype,从而拥有run属性。另外,让Man拥有一个属性name
目标
Human.call(this,name) 将this(new的时候,this指Man实例)传进去,让this.name等于传进去的name。
如何实现
注意:IE不支持上面第二句的写法,须换成:
var f=function(){}
f.prototype=Human.prototype
Man.prototype=new f()

现在,我们来验证一下man每一层的原型链:


成功实现继承

从内存的角度来剖析:


关于继承的一张很重要的图
继承的两种写法:
 function Human(name){
     this.name = name
 }
 Human.prototype.run = function(){
     console.log("我叫"+this.name+",我在跑")
     return undefined
 }
 function Man(name){
     Human.call(this, name)
     this.gender = '男'
 }

 var f = function(){}
 f.prototype = Human.prototype
 Man.prototype = new f()

 Man.prototype.fight = function(){
     console.log('糊你熊脸')
 }

ES 6 写法:

 class Human{
     constructor(name){
         this.name = name
     }
     run(){
         console.log("我叫"+this.name+",我在跑")
         return undefined
     }
 }
 class Man extends Human{
     constructor(name){
         super(name)
         this.gender = '男'
     }
     fight(){
         console.log('糊你熊脸')
     }
 }
上一篇 下一篇

猜你喜欢

热点阅读