请大家指点一个 javaScript 继承代码,代码如下

2016-04-27 15:23:08 +08:00
 palmers
function Person() {
	this.sname = '测试' ;
	this.age = 23 ;
	this.sex = '男' ;
	Person.prototype.say = function() {
		return this.sname + ' , ' + this.age + ' , ' + this.sex ;
	} ;
}


function Student() {

	Student.prototype = new Person() ;
	Student.prototype.constructor = Student ;
	this.school = 'xxx 大学' ;
}

var stu = new Student() ;
alert(stu.__proto__) ;
alert(stu.sname) ; //undefined

为什么stu 没有继承Person 的属性呢? 只能访问自己的。 Student 的原型是[object Object], 请大家指点!谢谢大家!

3005 次点击
所在节点    程序员
23 条回复
ykjsw
2016-04-27 15:29:35 +08:00
第一次 var stu = new Student() ;的时候, function Student 里面的 Student.prototype = new Person() ; 还没来得及执行

你再次执行一次
var stu = new Student() ;
alert(stu.__proto__) ;
alert(stu.sname) ;

就是正确的了
mrsatangel
2016-04-27 15:37:04 +08:00
Student.prototype = new Person() ;
Student.prototype.constructor = Student ;
移出构造函数体内
mrsatangel
2016-04-27 15:39:37 +08:00
原因是执行 var stu = new Student() ;的时候在 Student 这个函数里面执行了修改 Student 的 prototype 的行为,但是这个修改不会影响当前这个 stu 对象的构造,也就是说当前的 stu 对象实际上并没有继承 Person 。再一次使用 Student 构造函数的时候所构造的实例才继承了 Person
suikator
2016-04-27 15:42:30 +08:00
这种继承写法不太好吧,万一 Person 是有参的怎么办
jsonline
2016-04-27 15:47:28 +08:00
因为链接 __proto__ 与 prototype 是构造的最后一步
palmers
2016-04-27 15:52:15 +08:00
@ykjsw 为什么呢?
palmers
2016-04-27 15:53:08 +08:00
@mrsatangel 这个在哪里可以找到官方解释呢?
palmers
2016-04-27 15:53:37 +08:00
@suikator 恩 我随便举例的
jsonline
2016-04-27 15:57:37 +08:00
learnshare
2016-04-27 16:01:01 +08:00
sex 不是性别, gender 才是;
#2 的回答比较合适,可以翻翻 JS 权威指南第 6 版,其他书里也应该有讲到类和继承的实现方式
palmers
2016-04-27 16:04:34 +08:00
@jsonline 谢谢
palmers
2016-04-27 16:05:22 +08:00
@learnshare 嘿嘿 随便取的 我去看看 谢谢!
sodatea
2016-04-27 16:25:16 +08:00
new 的过程

## ES5
1. new: https://es5.github.io/#x11.2.2
2. 我们只关心最后一步,调用 [[Construct]] https://es5.github.io/#x13.2.2
3. 设置 prototype 在 5-7 步,调用构造函数在第 8 步,晚于前者

## ES2017
流程是类似的,不过用词改了很多
1. https://tc39.github.io/ecma262/#sec-evaluatenew
2. https://tc39.github.io/ecma262/#sec-ecmascript-function-objects-construct-argumentslist-newtarget
3. 设置 prototype 属性在第 5.a 步, OrdinaryCreateFromConstructor 方法 https://tc39.github.io/ecma262/#sec-ordinarycreatefromconstructor
调用构造函数是第 11 步

通俗的解释就是 MDN 上说的那些
palmers
2016-04-27 16:33:12 +08:00
@sodatea 非常感谢 非常感谢! 很全面!
kisnows
2016-04-27 16:50:43 +08:00
```
function Student() {
Student.prototype = new Person() ;
Student.prototype.constructor = Student ;
this.school = 'xxx 大学' ;
return Student.prototype
}
```
你可以这样改一下,虽然还是肯定不对,但是这样应该会好一点。
其实就像 2 楼说的,你新建 student 实例的时候, Student 的 prototype 上还什么都没有。你需要理解一下 new 操作符都干了哪些事情,可以看看我的这篇文章,也许可以帮助你理解。
[JavaScript 中的类和继承]( https://www.kisnows.com/2016/03/21/class%20and%20inherit%20in%20JavaScript/)
palmers
2016-04-27 18:44:20 +08:00
@kisnows 好的 谢谢!
SmiteChow
2016-04-27 21:42:38 +08:00
martianyi
2016-04-28 00:29:55 +08:00
es6 大法好,说实话, es5 我也不会这么写
palmers
2016-04-28 09:02:10 +08:00
@SmiteChow 谢谢 提供代码实例, 但是对我来说好深奥哦~~ 我大概能理解到是使用空对象来桥接实现继承? 不知道我理解的对不对 非常感谢!!! 请问 您的链接后面 "显示 Gist 代码" 是怎么做到的? 是什么 markdown 语法
palmers
2016-04-28 09:02:32 +08:00
@martianyi 嘿嘿 我是前端小白 见笑

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/274805

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX