我不是那种动态编程语言,但是我写了很多JavaScript代码.我从来没有真正了解这个基于原型的编程,有没有人知道这是如何工作的?
var obj = new Object();
obj.prototype.test = function() { alert('Hello?'); };
var obj2 = new obj();
obj2.test();
Run Code Online (Sandbox Code Playgroud)
我记得很久以前我和人们进行了很多讨论(我不确定我在做什么)但是据我所知,没有一个类的概念.它只是一个对象,这些对象的实例是原始的克隆,对吧?
但是JavaScript中这个".prototype"属性的确切目的是什么?它与实例化对象有什么关系?
var obj = new Object(); // not a functional object
obj.prototype.test = function() { alert('Hello?'); }; // this is wrong!
function MyObject() {} // a first class functional object
MyObject.prototype.test = function() { alert('OK'); } // OK
Run Code Online (Sandbox Code Playgroud)
这些幻灯片也非常有帮助.
以下两个声明之间有什么区别?
Class.method = function () { /* code */ }
Class.prototype.method = function () { /* code using this.values */ }
Run Code Online (Sandbox Code Playgroud)
是否可以将第一个语句视为静态方法的声明,将第二个语句视为实例方法的声明?
function Gadget(name, color)
{
this.name = name;
this.color = color;
}
Gadget.prototype.rating = 3
var newtoy = new Gadget("webcam", "black")
newtoy.constructor.prototype.constructor.prototype.constructor.prototype
Run Code Online (Sandbox Code Playgroud)
它总是返回rating = 3的对象.
但如果我做以下事情:
newtoy.__proto__.__proto__.__proto__
Run Code Online (Sandbox Code Playgroud)
链条最终返回null.
另外在Internet Explorer中,如果没有__proto__属性,我如何检查null ?
考虑这个功能:
function Foo(){
var a = "3";
};
Run Code Online (Sandbox Code Playgroud)
根据__proto__ VS. JavaScript中的原型,
Foo.__proto__ = Function.prototype
Function.prototype.__proto__ = Object.prototype
Run Code Online (Sandbox Code Playgroud)
我理解了这一部分,但如果我在Google Chrome控制台中执行此操作:
Object.__proto__
output: ƒ () { /* native code */ }
Function.__proto__
output: ƒ () { /* native code */ }
Run Code Online (Sandbox Code Playgroud)
Q1:他们为什么指向功能?它们实际上是什么Function以及Object它们如何彼此不同,因为Object实际上是一个函数?:
typeof Object
"function"
Run Code Online (Sandbox Code Playgroud)
Q2:如果一切都是JavaScript中的对象,那为什么是Object函数?另外,如何在JavaScript中实际实现一个函数?在函数内声明的变量会发生什么?函数是否由JavaScript编译器转换为对象?
对不起,如果我错过了一些明显的事 我真的很困惑函数和对象在JavaScript中的实现方式.
在Node.js的Express模块的代码中,我遇到了这一行,为服务器设置了继承:
Server.prototype.__proto__ = connect.HTTPServer.prototype;
Run Code Online (Sandbox Code Playgroud)
我不知道这是什么一样-在MDC文档(https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_Revisited#prototype_and_ 原)好像说我可能只是这样做:
Server.prototype = connect.HTTPServer.prototype;
Run Code Online (Sandbox Code Playgroud)
的确,我做了这个测试:
var parent = function(){}
parent.prototype = {
test: function(){console.log('test')};
}
var child1 = function(){};
child1.prototype = parent.prototype;
var instance1 = new child1();
instance1.test(); // 'test'
var child2 = function(){};
child2.prototype.__proto__ = parent.prototype;
var instance2 = new child2();
instance2.test(); // 'test'
Run Code Online (Sandbox Code Playgroud)
看起来一样吗?所以,是的,我想知道设置object.prototype .__ proto是为了什么.谢谢!
我画了下面的图片,演示了如何继承对象(函数构造函数标记为蓝色,从这些构造函数创建的对象标记为绿色):
以下是创建此类层次结构的代码:
function Figure() {}
function Rect() {}
Rect.prototype = new Figure();
function Square() {}
Square.prototype = new Rect();
function Ellipse() {}
Ellipse.prototype = new Figure();
function Circle() {}
Circle.prototype = new Ellipse();
Run Code Online (Sandbox Code Playgroud)
现在我想检查是否new Square()继承自Rect,所以这是我期望JavaScript引擎检查它:
var s = new Square();
s instanceof Rect // ?
s.__proto__ === Rect.prototype // false
new Rect() new Figure()
s.__proto__.__proto__ === Rect.prototype // true
new Figure() new Figure()
Run Code Online (Sandbox Code Playgroud)
所以s instanceof Rect应该回来true.这是预期的,实际上是我运行代码时返回的内容.但后来我想检查是否new Circle()继承自Rect,所以我遵循相同的逻辑:
var …Run Code Online (Sandbox Code Playgroud) 我已经看到,在许多情况下,js中的继承可以像这样实现
function Organism(age) {
this.age = age;
}
Organism.prototype.growOlder = function(){ this.age = this.age + 1}
var org = new Organism("1000");
function Human(name,age){
Organism.call(this,age); //this sets up the properties on the human object
this.name = name;
}
Human.prototype = Object.create(Organism)
Human.prototype.constructor = Human; //sets the constructor
Human.prototype.run = function(){ console.log(this.name + "run")}
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果有人可以详细解释为什么Object.create(Organism)是必要的,只是这样做
Human.prototype = Organism.prototype
Run Code Online (Sandbox Code Playgroud)
是不够的.原型链看起来像
没有object.create:
Human.__proto__ -> Organism __proto__-> Object
with object.create:
Human.__proto__-> IntermediateObject.__proto__ -> Organism.__proto__-> Object
感谢您的时间.
编辑:我知道es6类并继承语法糖.我只是好奇如何在较低的层面上工作.
我有下面的构造函数和SubType原型指向SuperType的实例。当我这样做时,x.isPrototypeOf(SubType.prototype)它会返回false。我很困惑,因为我已明确将其设置x为的原型SubType。有人可以告诉我为什么会这样吗?
function SuperType(){}
function SubType(){}
x = new SuperType();
SubType.prototype = x;
SubType.prototype.constructor = SubType;
console.log(x.isPrototypeOf(SubType)) // returns false
console.log(SuperType.prototype.isPrototypeOf(SubType.prototype)) // returns trueRun Code Online (Sandbox Code Playgroud)