实例对象和new
---------------------------------------------------------------------------------------------------------------------
1. 对象是单个实物的抽象, 是一个容器,封装了属性和方法。
2. 生成一个对象需要一个模板,javascript语言用构造函数(constructor)
作为对象的模板。
3. new命令是执行构造函数,返回对象实例。
new命令本身可以执行构造函数,所以后面的构造函数可以带括号也可以不带。
如果直接调用构造函数,不使用new。那么构造函数里面的this 将会代表全局对象。
所以这种时候,构造函数里面的属性也就成了全局属性和方法。
避免忘记写new,可以这样处理。
1. 在构造函数内部对this 的类型进行判断,不是当前构造函数类型的对象,就new 一个。
2. 或者在构造函数里面添加use strict。 因为函数内部严格模式 this不能指向全局变量。
new命令原理
使用new 执行下面的步骤
1. 创建一个空对象,作为要返回的实例
2. 将这个空对象的原型指向构造函数的prototype属性。
3. 将空对象复制给函数内部的this
4, 执行构造函数内部的代码。
手写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);
函数内部可以使用new.target,如果是当前函数new命令调用,指向当前函数,否则指向undefined。
4. 创建对象如果拿不到构造函数,可以用现有的对象作为模板。使用Object.create().实现。
----------------------------------------------------------------------------------------------------------------------
this
简单说,this
就是属性或方法“当前”所在的对象。
由于对象的属性可以赋给另一个对象,所以属性所在的当前对象是可变的,即this
的指向是可变的。
实质:
this的设计和内存结构有关系。
函数本身存在内存中,我们将函数赋予一个对象的属性是,是调用的函数的引用地址。
这个时候函数体内部,引用当前环境的其他变量。变量是有运行环境提供,this就出现了
它代表函数当前的运行环境。
使用场合
1. 全局环境
this指的是顶层对象 window.
2. 构造函数this。指的是实例对象
3. 对象方法的this.指的是方法运行时所在的对象
JavaScript提供了call、apply、bind这三个方法来切换this的指向。
apply和call唯一区别是它接受一个数组作为函数执行时的参数
将方法的this指向改变,并且调用执行该方法。
bind()
方法用于将函数体内的this
绑定到某个对象,然后返回一个新函数。
JavaScript 不提供找出数组最大元素的函数。结合使用apply
方法和Math.max
方法,就可以返回数组的最大元素。
var a = [10, 2, 4, 15, 9]; Math.max.apply(null, a) // 15
-------------------------------------------------------------------------