JavaScript的继承机制详谈

目录

一. this关键字

1.涵义

2.实质

3. this与变量作用域

4. 绑定this的方法

二. 对象的创建

1. 什么是对象

2. 构造函数

3. new命令 

1)new命令的作用

2)new命令的原理

4. Object.create()

三. JavaScript的继承机制

1. 基于原型链的继承

2. 原型prototype & 构造函数constructor

3. instanceof运算符


一. this关键字

 1.涵义

JavaScript语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象之中运行,this就是函数运行时所在的对象(环境)。

2.实质

js引擎会将函数单独保存在内存中,函数是一个单独的值,其引用地址可以赋值给任意对象的属性,因此它可以在不同的环境执行。为了在函数体内部获得当前的运行环境(context),this关键字被设计出来。

注:

  • this的指向是不确定的,常用解决方法就是使用中间变量固定this的值。
  • 如果this所在的方法不在对象的第一层,这时this只是指向当前一层的对象,而不会继承更上面的层。
3. this与变量作用域

函数运行时的this关键字和其变量作用域并不是一种概念。this的值取决于函数是如何被调用的,而变量作用域则是由函数的编写方式决定的。

4. 绑定this的方法

1)Function.prototype.call()

func.call(thisValue,arg1,arg2,...)

  call的第一个参数就是this所要指向的那个对象,后面的参数则是函数调用时所需的参数。

注:hasOwnProperty(propertyName)方法是用来检测属性是否为对象的自有属性,如果是,返回true,否者false。

2)Function.prototype.apply()

func.apply(thisValue, [arg1, arg2, ...])

  apply的第一个参数是this所要指向的那个对象;第二个参数是一个数组,即传入原函数的参数。

注:call()和apply()方法不仅绑定函数执行时所在的对象,还会立即执行函数。

3)Function.prototype.bind()

bind方法用于将函数体内的this绑定至某个对象,然后返回一个新函数。

二. 对象的创建

1. 什么是对

对象是一个容器,封装了属性(property)和方法(method)

2. 构造函数

构造函数用来生成对象实例,JavaScript语言使用构造函数作为对象的模板。它就是一个普通的函数,但有自己的特征和用法。

构造函数的特点:

  • 函数体内部使用了this关键字,代表了所要生成的对象实例。
  • 生成对象的时候,必须使用new命令。
3. new命令 
1)new命令的作用

就是执行构造函数,返回一个实例对象。若忘记使用new,则构造函数会变成普通函数,不会生成一个实例对象。

2)new命令的原理

使用new命令时,实际执行的步骤

  • 创建一个空对象,作为要返回的对象实例。
  • 将这个空对象的原型(属性_proto_),指向构造函数的prototype属性。
  • 将这个空对象赋值给函数内部的this关键字
  • 执行构造函数内部的代码

 注:如果构造函数内部有return语句,且return后面跟着一个对象,则new命令会返回return语句指定的对象;否则,总会返回this对象。

 new命令简化的内部流程

function _new(/* 构造函数 */ constructor, /* 构造函数参数 */ params) {
  // 将 arguments 对象转为数组
  var args = [].slice.call(arguments);
  // 取出构造函数
  var constructor = args.shift();
  // 创建一个空对象,继承构造函数的 prototype 属性
  var context = Object.create(constructor.prototype);
  // 执行构造函数
  var result = constructor.apply(context, args);
  // 如果返回结果是对象,就直接返回,否则返回 context 对象
  return (typeof result === 'object' && result != null) ? result : context;
}

// 实例
var actor = _new(Person, '张三', 28);
4. Object.create()

Object.create()方法接受一个对象作为参数,然后以它为原型,返回一个实例对象。

该方法的实质是,新建一个空的构造函数F,然后让F.prototype属性指向参数对象obj,最后返回一个F的实例,从而实现让该实例继承obj的属性。

三. JavaScript的继承机制

1. 基于原型链的继承

JavaScript的继承实现方式,基于原型链。读取对象的某个属性时,当实例对象自身没有某个属性或方法时,它会到原型对象去寻找该属性或方法,如果还是找不到,就到原型的原型去寻找,最终可以上溯到Object.prototype

2. 原型prototype & 构造函数constructor
1)原型与构造函数的关系

一般情况,构造器决定的是属性,原型决定的是功能。构造器(contructor)和原型(prototype)共同决定一个对象。

原型对象的constructor指向构造函数,构造函数的prototype指向原型对象。

  • 每创建一个函数,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象
  • 当调用一个函数创建一个新的实例后,该实例的内部将包含一个指针_proto_,指向构造函数的原型对象
  • 默认原型都是Object的实例

一个对象实例的原型链,如图: 

 

2)Function对象 

函数也是对象,可以看作是由构造函数Function实例化的对象,其原型对象就是Function的原型对象,关系如图所示

3)prototype属性的作用

原型对象prototype的作用,就是定义所有实例对象共享的属性和方法,从而节省内存空间。

4)constructor属性的作用 

可以得知某个实例对象,到底是哪一个构造函数产生的。

修改原型对象时,一般要同时修改constructor属性的指向。

3. instanceof运算符

instanceof运算符返回一个布尔值,表示对象是否为某个构造函数的实例。

它的原理是检查右边构造函数的prototype属性,是否在左边对象的原型链上。

参考文献

js的面向对象编程 --- 阮一峰

JavaScript的原型链

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值