有人可以解释javascript原型继承

ekh*_*led 7 javascript oop

我想知道是否有人能够function.prototype在OO javascript中解释这个东西(thingie !! ??).

我来自服务器端编程背景,可能是我没有抓住原型的整个概念,

给出以下代码片段:

var animate=function(){};
animate.angular=function(){/*does something here*/};
animate.circular=function(){/*does something here*/};
Run Code Online (Sandbox Code Playgroud)

var animate=function(){};
animate.prototype.angular=function(){/*does something here*/};
animate.prototype.circular=function(){/*does something here*/};
Run Code Online (Sandbox Code Playgroud)

据我所知,后两个函数都可以通过调用animate.angular(/*args*/),animate.circular(/*args*/)所以,我想我的问题是,以第二种方式定义函数的优点是什么?以及他们如何或为何与众不同?

希望我有道理......

编辑: 谢谢你所有的启发性答案,很难在这里判断答案是"正确的",所以我要标记一个我觉得最有贡献的答案......

你们当然给了我更多思考的东西......

小智 6

我想你的意思是在你的例子中的某个地方设置一个等于new animate()的东西.如果不使用新的,我会详细说明会发生什么:

var animate = function(){ console.log(0, 'animate'); };
animate.angular = function(){ console.log(1, 'animate.angular'); };
animate.circular = function(){ console.log(2, 'animate.circular'); };

animate.prototype.angular = function(){ console.log(3, 'animate.prototype.angular'); };
animate.prototype.circular = function(){ console.log(4, 'animate.prototype.circular'); };
Run Code Online (Sandbox Code Playgroud)

只有前两个函数#1和#2可以从animate变量中调用.

animate.angular();
animate.circular();
Run Code Online (Sandbox Code Playgroud)

如果你创建一个新的animate(),你可以调用接下来的两个,#3和#4,(但不是#1或#2).

var ani2 = new animate();

ani2.angular();
ani2.circular();
Run Code Online (Sandbox Code Playgroud)

此外,animate()是一个函数,但ani2不是.

console.log(5, typeof animate);
console.log(6, typeof ani2);
console.log(7, animate());
Run Code Online (Sandbox Code Playgroud)

虽然已经创建了ani2,但您可以通过animate.prototype向其添加新成员.

animate.prototype.bark = function(){ console.log(8, 'bark'); };
ani2.bark();
Run Code Online (Sandbox Code Playgroud)

然而,animate变量并不继承它的原型.

console.log(9, typeof ani2.bark);
console.log(10, typeof animate.bark);
Run Code Online (Sandbox Code Playgroud)

请注意,ani2不会继承直接应用于animate变量的成员.它只继承自animate.prototype.

animate.paperclip = function(){ console.log(11, "paperclip"); };

animate.paperclip();
console.log(12, typeof ani2.paperclip);
console.log(13, typeof animate.paperclip);
Run Code Online (Sandbox Code Playgroud)

您还可以在构造函数(如animate)中使用this关键字将实例成员添加到子级.

var Anime = function(a,b){ this.a=a; this.b=b; this.c=console; };
var anime1 = new Anime(14, 'anime1');
var anime2 = new Anime(15, 'anime2');
anime1.c.log(anime1.a, anime1.b);
anime2.c.log(anime2.a, anime2.b);

Anime.prototype.a = 16;
Anime.prototype.z = 'z';

var anime3 = new Anime(17, 'anime3');
anime3.c.log(18, anime3.a, anime3.b, anime3.z, " ", anime2.a, anime2.b, anime2.z, " ", anime1.a, anime1.b, anime1.z);
anime2.z='N';
anime3.c.log(19, anime3.a, anime3.b, anime3.z, " ", anime2.a, anime2.b, anime2.z, " ", anime1.a, anime1.b, anime1.z);
Run Code Online (Sandbox Code Playgroud)

内存被自动分配给anime2.z的单独实例,因为它被修改,anime1和anime3仍然"共享"一个节俭的未修改z.

a,b和c成员不是以同样的方式"共同".它们是在构造函数中使用分配的,新的Anime(),(不是从Anime.prototype继承).此外,原型上的a成员将始终由构造函数"个性化".

永远不要忘记新的关键字,或者它都不会像它应该的那样工作.例如,指向一个名为without new的构造函数中的全局对象.

console.log(20, typeof window.a, typeof window.b, typeof window.c);
var opps = Anime(21, 'zapp');
console.log(22, typeof window.a, typeof window.b, typeof window.c);
console.log(23, typeof opps);
Run Code Online (Sandbox Code Playgroud)

这是输出.汤姆的第二个暗示道格拉斯·克罗克福德的视频!


/*
1 animate.angular
2 animate.circular
0 animate
3 animate.prototype.angular
4 animate.prototype.circular
5 function
6 object
0 animate
7 undefined
8 bark
9 function
10 undefined
11 paperclip
12 undefined
13 function
14 anime1
15 anime2
18 17 anime3 z 15 anime2 z 14 anime1 z
19 17 anime3 z 15 anime2 N 14 anime1 z
20 undefined undefined undefined
22 number string object
23 undefined
*/
Run Code Online (Sandbox Code Playgroud)