从PHP的角度看JS的原型
提示:这是一篇JS的讲解文档
前言
JS的原型是JS的很重要的知识,为后续学习理解一些问题和代码的逻辑的总要基础,但是JS的原型又很绕,导致笔者也有类似的觉得很晕的地方,现在就以PHP面向对象的角度来对比着学习JS原型,解开JS原型的面纱。
提示:笔者也是刚刚开始研究,难免有解释不得当的地方,如有纰漏,请指正。
一、JS中的方法和PHP中的类
1.JS原型是什么?
原型是JS为了能够像后端语言一样可以进行面向对象编程而引入的。面向对象的三大法宝,封装、继承、多态。原型是为了解决继承的问题。来看PHP中的继承:
Class Person(){
public function sayHello(){
echo "你好!";
}
}
Class Man extends Person(){
public function showGender(){
echo "我是男生!";
}
}
$man = new Man();
$man->sayHello();//你好!
一个最简单的继承用PHP就写好了。实例化Man后就可以调用Person中的sayHello方法。
那么这个内容要在JS中该如何实现呢?来看JS的做法。
function Person(){
this.sayHello = function(){
console.log('你好!');
}
}
function Man(){
this.showGender = function(){
console.log('我是男生!');
}
}
Man.prototype = new Person();
//或者写成Man.__proto__ = new Person();
var man = new Man();
man.sayHello();//控制台输出:你好!
JS是一门神奇的语言,function其实也是对象:那么我们还可以这样来写:
var person = {
sayHello:function(){
console.log('你好!');
}
}
var man = {
showGender:function(){
console.log('我是男生!');
},
__proto__:person
}
man.sayHello();
这里最让人绕的地方就是__proto__ 和 prototype这俩个内容。虽然这俩个内容看起来是相同的,但是却不能互换,在对象中是没有prototype的属性的(在PHP中就是类的属性,或者说字段)。
只要深刻了解了__proto__ 和prototype之间的区别就算是把原型弄懂了。
从PHP的角度来看,__proto__和prototype就是类似extends的东西,PHP中类的继承用extends,那现在JS变成了__proto__和prototype。这样理解是不是就容易点了。
2.原型链
js中所有的对象(对象就包括了function)的__proto__都指向了object.prototype。来看代码。
var person = {
sayHello:function(){
console.log('你好!');
}
}
var man = {
showGender:function(){
console.log('我是男生!');
},
__proto__:person
}
// man.sayHello();
console.log(man);
可以看到,man对象中__proto__ 指向了sayHello(我们制定的),而sayHello的__proto__ 的constructor指向了object或者说__proto__指向了object.prototype.看下简单的示意图:
看到这幅图是不是有点明白了,绕的地方就是对象的__proto__指向了object.prototype,而object.prototype中呢,有个构造函数constructor,它指向object。
而function又是一个特殊的对象,它和object是一样的(都拥有一个prototype,而prototype中又存在一个constructor指向function)。