欢迎来真孝善网,为您提供真孝善正能量书籍故事!

深入解析:构造函数内部方法与原型链上方法的区别

时间:10-27 名人轶事 提交错误

今天给各位分享深入解析:构造函数内部方法与原型链上方法的区别的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

首先我们先了解一下这篇文章的重点:函数内的方法:使用函数内的方法我们可以访问到函数内部的私有变量,如果我们从构造函数new出来的对象需要我们操作构造函数内部的私有变量,

这时候就要考虑使用函数内的方法了。prototype上的方法:当我们需要通过一个函数创建大量的对象时,并且这些对象有很多方法;那么我们必须考虑将这些方法添加到函数的原型中。

这样的话,我们的代码内存占用就比较小了。在实际的应用中,这两种方法往往是结合使用的;所以我们要首先了解我们需要的是什么,然后再去选择如何使用.让我们根据下面的代码来解释一下这些点。以下是代码部分:

//构造函数A

函数A(名称){

this.name=名称|| "一个";

this.sayHello=函数() {

console.log("你好,我的名字是:" + this.name);

}

}

//构造函数B

函数B(名称) {

this.name=名称|| "b";

}

B.prototype.sayHello=function() {

console.log("你好,我的名字是:" + this.name);

};

var a1=new A("a1");

var a2=new A("a2");

a1.sayHello();

a2.sayHello();

var b1=new B("b1");

var b2=new B("b2");

b1.sayHello();

b2.sayHello();我们首先写了两个构造函数,第一个是A,里面包含一个方法sayHello;第二个是构造函数B,

我们在构造函数B的prototype属性上编写了sayHello方法。

需要指出的是,通过这两个构造函数new创建的对象具有相同的属性和方法,但它们的区别可以用下图来说明:

1 我们使用构造函数A创建了两个对象a1和a2;我们使用构造函数B 创建了两个对象b1 和b2;我们可以找到这两个对象b1和b2的sayHello方法。

它们都指向其构造函数的prototype属性的sayHello方法。 a1和a2都在内部定义了这个方法。

定义在构造函数内部的方法,会在它的每一个实例上都克隆这个方法;定义在构造函数的prototype属性上的方法会让它的所有示例都共享这个方法,但是不会在每个实例的内部重新定义这个方法.如果我们的应用需要创建很多新的对象,并且这些对象还有许多的方法,为了节省内存,我们建议把这些方法都定义在构造函数的prototype属性上当然,在某些情况下,我们需要在构造函数中定义某些方法。这通常是因为我们需要访问构造函数内部的私有变量

下面我们给出一个将两者结合起来的例子,代码如下:

函数人(姓名,家庭){

this.name=名称;

this.family=家庭;

var 记录=[{type: "in", amount: 0}];

this.addTransaction=函数(trans) {

if(trans.hasOwnProperty("类型") trans.hasOwnProperty("金额")) {

记录.push(trans);

}

}

this.balance=函数() {

总变量=0;

记录.forEach(函数(记录){

if(record.type==="in") {

总计+=记录.金额;

}

别的{

总计-=记录.金额;

}

});

返回总计;

};

};

Person.prototype.getFull=function() {

返回this.name + " " + this.family;

};

Person.prototype.getProfile=function() {

return this.getFull() + ", 总余额: " + this.balance();

};在上面的代码中,我们定义了一个Person构造函数;这个函数有一个内部私有变量记录,我们不想通过函数内部以外的方法访问它。

为了操作这个变量,我们把操作这个变量的所有方法都写在了函数内部。并且我们在Person的prototype属性上编写了一些公共方法,例如方法getFull和getProfile。

把方法写在构造函数的内部,增加了通过构造函数初始化一个对象的成本,把方法写在prototype属性上就有效的减少了这种成本.你也许会觉得,调用对象上的方法要比调用它的原型链上的方法快得多,其实并不是这样的,如果你的那个对象上面不是有很多的原型的话,它们的速度其实是差不多的另外,一些需要注意的事项:

首先,如果在函数的原型属性上定义方法,则必须记住,如果更改方法,则该构造函数生成的所有对象的该方法都将更改。还有一点就是变量提升的问题,我们可以简单看一下下面的代码:func1(); //这里会报错,因为函数执行时func1还没有赋值。 error: func1 不是一个函数

var func1=函数() {

console.log("func1");

};

func2(); //这将正确执行,因为函数声明将被提升。

函数func2() {

console.log("func2");

关于对象序列化的问题。函数原型上定义的属性不会被序列化。可以看到如下代码:function A(name) {

this.name=名称;

}

A.prototype.sayWhat="说什么.";

var a=new A("dreamapple");

console.log(JSON.stringify(a));我们可以看到输出结果是{"name":"dreampapple"}引用的文章或问答:

用户评论

裸睡の鱼

感觉这篇文章讲得就很深入,我总是对构造函数不太明白...

    有20位网友表示赞同!

太难

学习JavaScript就离不开了解构造函数和原型链的概念啊

    有17位网友表示赞同!

杰克

之前不知道这两个方法有什么区别,看来需要好好学习一下了

    有5位网友表示赞同!

抓不住i

我的项目里经常使用到构造函数,希望这篇文章能给我带来一些新思路

    有11位网友表示赞同!

丢了爱情i

原来在构造函数里面写的方法,和定义在 prototype 上的又不一样啊?

    有14位网友表示赞同!