JS构造函数里的属性方法与原型上的属性方法的区别

2,172 阅读2分钟
1. 把方法写在原型上比写在构造函数里消耗内存更小,因为一个类的原型只有一个,写在原型上的方法可以被所有实例共享,实例化的时候并不会在实例中再复制一份;

2. 写在构造函数里的方法,在实例化的时候,会在每一个实例对象上面复制一份,所以消耗的内存更高,因此我们一般把属性定义在构造函数里,把方法定义在原型上

3. 在构造函数里定义的属性方法要比原型中的优先级更高,如果定义了同名的属性或方法,则构造函数里的会覆盖原型上面的

注意:

  • 定义在构造函数内部的方法,会在它的每一个实例上,都克隆这个方法;
  • 定义在构造函数prototype属性上的方法,会让它的所有实例都共享这个方法,但是不会在每个实例内部,重新定义这个方法。
  • 如果我们的应用需要创建很多的对象,并且这些对象还有许多的方法,为了节省内存,我们建议把这些方法都定义在构造函数的prototype属性上。


还有一点就是变量提升的问题,我们可以稍微的看一下下面的代码:

func1();  //这里会报错,因为在函数执行的时候,func1还没有被赋值, error: func1 is not a function

var func1 = function(){
    console.log('func1');
}


func2(); // 这个会被正确执行,因为函数的声明会被提升.

function func2() {
  console.log('func2');

}

关于对象序列化的问题。定义在构造函数prototype上的属性,不会被序列化。可以看下边代码:

function A(name) {

  this.name = name;

}

A.prototype.sayWhat = 'say what...';


var a = new A('dreamapple');

console.log(JSON.stringify(a));  //  {"name":"dreamapple"}