目录
2. 原型prototype & 构造函数constructor
一. 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属性,是否在左边对象的原型链上。
参考文献