Skip to content

new

对象

面向对象编程(Object Oriented Programming 即 OOP),表明了对象是单个实物的抽象,其也是一个容器,封装了属性和方法的集合。

构造函数和普通函数

什么是构造函数?

其就是专门用来生成实例对象的函数,也是对象的模板,描述对象的基本结构。在 JS 中构造函数有两个特点:

  1. 函数体内部使用了 this 关键字,代表了所要生成的对象实例。
  2. 生成对象的是时候,必须使用 new 命令。
  3. 建议构造函数首字母大写(为与普通函数区分)。

new

js
var Dog = function(name) {
	this.name = name || '小黑';
}

var dog1 = new Dog();
console.log(dog1.name);

如果忘记使用new命令

js
var Dog = function(name) {
	this.name = name || '小黑';
}

var dog1 = Dog();
console.log(dog1);        // undefined
console.log(name);        // '小黑'
console.log(dog1.name);   // 报错

如何解决?

1. use strict
js
var Dog = function(name) {
    "use strict";
	this.name = name || '小黑';
}

var dog1 = Dog();         // TypeError: Cannot set property 'name' of undefined
2. 判断是否使用 new 命令
js
var Dog = function(name) {
    if(!(this instanceof Dog)){
        return new Dog(...arguments);
    }
    this.name = name || '小黑';
}

var dog1 = Dog();
3. new.target

在函数的内部 如果当前函数是new 命令调用,则new.target指向当前函数,否则为undefined

js
var Dog = function(name) {
    if(!new.target){
        return new Dog(...arguments);
    }
    this.name = name || '小黑';
}

var dog1 = Dog();

new 命令的原理

  1. 创建一个空对象,作为将要返回的对象实例。
  2. 将这个空对象的原型,指向构造函数的prototype属性。
  3. 将这个空对象赋值给函数内部的this关键字
  4. 开始执行构造函数内部的代码

new 命令的简化流程

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

return

  1. 如果构造函数内部有return 语句,而且return 后面跟着一个对象,new命令会返回return语句指定的对象,否则就会不管return语句,返回this对象。
js
// 1. return 返回一个常量,而不是对象
var Dog = function(name) {
    this.name = name || '小黑';
    return 111
}
var dog = new Dog(); 
console.log(dog);     // { name : ‘小黑’}

// 2. return 返回一个数组
var Dog3 = function(name) {
    this.name = name || '小黑';
    return []
}
var dog3 = new Dog3(); 
console.log(dog3);      // []


// 3. return 返回一个空的对象
var Dog1 = function(name) {
    this.name = name || '小黑';
    return {}
}
var dog1 = new Dog1(); 
console.log(dog1);      // { }

// 4. 没有return 返回
var Dog2 = function(name) {
    this.name = name || '小黑';
}
var dog2 = new Dog2(); 
console.log(dog2);       // { name : ‘小黑’}