给出以下代码:
function a() {}
function b() {}
b.prototype = new a();
var b1 = new b();
Run Code Online (Sandbox Code Playgroud)
我们可以留下a已被添加到b原型链中.大.并且,以下所有都是真的:
b1 instanceof b
b1 instanceof a
b1 instanceof Object
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果我们不知道b1提前的起源怎么办?我们怎样才能发现其原型链的成员?理想情况下,我喜欢像[b, a, Object]或的数组["b", "a", "Object"].
这可能吗?我相信我已经在SO上找到了一个答案,描述了如何找到这个,但我不能再为我的生活找到它.
如何在不修改原型的情况下扩展核心JavaScript类型(String,Date等)?例如,假设我想用一些方便的方法创建一个派生的字符串类:
function MyString() { }
MyString.prototype = new String();
MyString.prototype.reverse = function() {
return this.split('').reverse().join('');
};
var s = new MyString("Foobar"); // Hmm, where do we use the argument?
s.reverse();
// Chrome - TypeError: String.prototype.toString is not generic
// Firefox - TypeError: String.prototype.toString called on incompatible Object
Run Code Online (Sandbox Code Playgroud)
该错误似乎源自String基本方法,在这种情况下可能是"拆分",因为它的方法正在应用于某些非字符串对象.但是如果我们不能应用非字符串对象那么我们真的可以自动重用它们吗?
[编辑]
显然,我的尝试在很多方面存在缺陷,但我认为这证明了我的意图.经过一番思考后,似乎我们不能重用任何String原型对象的函数而不在String上显式调用它们.
是否可以扩展核心类型?
我刚刚进入JavaScript,我正试图围绕原型继承.似乎有多种方法可以达到同样的效果,所以我想看看是否有任何最佳实践或理由以一种方式做事.这就是我在说的:
// Method 1
function Rabbit() {
this.name = "Hoppy";
this.hop = function() {
console.log("I am hopping!");
}
}
// Method 2
function Rabbit() {}
Rabbit.prototype = {
name: "Hoppy",
hop: function() {
console.log("I am hopping!");
}
}
// Method 3
function Rabbit() {
this.name = "Hoppy";
}
Rabbit.prototype.hop = function() {
console.log("I am hopping!");
}
// Testing code (each method tested with others commented out)
var rabbit = new Rabbit();
console.log("rabbit.name = " + rabbit.name);
rabbit.hop();
Run Code Online (Sandbox Code Playgroud)
所有这些似乎都具有相同的效果(除非我遗漏了一些东西).那么一种方法优于另一种方法吗?你怎么做呢?
我已经看过很多像这样的东西了,我正在寻找基本的JavaScript继承的正确解决方案:
function Food(){} // Food constructor (class)
function Bread(){} // Bread constructor (class)
var basicFood = new Food(); // Food classes will inherit from this basicFood instance.
Bread.prototype = basicFood; // Bread now inherits from Food.
var bread = new Bread(); // We create some bread!
bread.constructor == Food; // Though, now we feel very uneasy about how
// the constructor is wrong,
Bread.prototype.constructor = Bread; // So we explicitly set the prototype's constructor
bread = new Bread(); // and …Run Code Online (Sandbox Code Playgroud) 我有一种情况需要检查构造函数(X)在其原型链中是否有另一个构造函数(Y)(或者是Y本身).
最快的方法可能是这样做(new X()) instanceof Y.在这种情况下,这不是一个选项,因为有问题的构造函数可能会在没有有效参数的情况下实例化.
我考虑的下一个方法是:
const doesInherit = (A, B) => {
while (A) {
if (A === B) return true;
A = Object.getPrototypeOf(A);
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
这是行得通的,但我无法摆脱这种感觉,即我错过了一些更简单的检查方法.有吗?
var obj = new XMLHttpRequest();
console.log("Object.keys():",Object.keys(obj));
console.log("Object.getOwnPropertyNames():",Object.getOwnPropertyNames(obj))
console.log("Object.entries():",Object.entries(obj))
console.log("JSON.stringify():",JSON.stringify(obj))
console.log("console.log:"); console.log(obj)
Run Code Online (Sandbox Code Playgroud)
输出:
Object.keys(): []
Object.getOwnPropertyNames(): []
Object.entries(): []
JSON.stringify(): {}
console.log:
XMLHttpRequest {onreadystatechange: null, readyState: 0, timeout: 0, withCredentials: false, 上传: XMLHttpRequestUpload, ...}
如何在 javascript 中创建这样一个对象,其属性仅使用 打印console.log(obj),但不由上述任何函数返回?
我已经尝试使用constructor function, object.create()(with enumerable:false), Object.assign(), using来创建对象,getters从类中初始化,从扩展类中初始化等
javascript prototype xmlhttprequest prototypal-inheritance ecmascript-6
我在js做了一些继承,以便更好地理解它,我发现了让我困惑的东西.
我知道当你用new关键字调用'constructor function'时,你得到一个新对象,引用该函数的原型.
我也知道,为了进行原型继承,你必须用你想成为'超类'的对象的实例替换构造函数的原型.
所以我做了这个愚蠢的例子来尝试这些概念:
function Animal(){}
function Dog(){}
Animal.prototype.run = function(){alert("running...")};
Dog.prototype = new Animal();
Dog.prototype.bark = function(){alert("arf!")};
var fido = new Dog();
fido.bark() //ok
fido.run() //ok
console.log(Dog.prototype) // its an 'Object'
console.log(fido.prototype) // UNDEFINED
console.log(fido.constructor.prototype == Dog.prototype) //this is true
function KillerDog(){};
KillerDog.prototype.deathBite = function(){alert("AAARFFF! *bite*")}
fido.prototype = new KillerDog();
console.log(fido.prototype) // no longer UNDEFINED
fido.deathBite(); // but this doesn't work!
Run Code Online (Sandbox Code Playgroud)
(这是在Firebug的控制台中完成的)
1)为什么如果所有新对象都包含对creator函数原型的引用,fido.prototype是未定义的?
2)继承链[obj] - > [constructor] - > [prototype]而不是[obj] - > [prototype]?
3)我们的对象(fido)的"原型"属性是否曾被检查过?如果是这样的话......为什么'deathBite'未定义(在最后一部分)?
此示例创建一个对象,冻结它,然后从冻结对象创建一个新对象.如果第二个对象尝试更改测试属性,则不能.它保持冻结,第一个对象的值为10.
//Create an object and freeze it
var first = {
test: 10
};
Object.freeze(first);
//Create a second object from the first one and
//try and change the new test property (you can't)
var second = Object.create(first);
second.test = 20;
console.log(second.test); //10
Run Code Online (Sandbox Code Playgroud)
这是我的问题:
是second.test新对象的新属性,还是只是对冻结的第一个对象中的属性的引用?
是否可以将冻结first.test用作默认值,但是second.test如果需要则覆盖它?
我问的原因是因为我想将一个不可变的基础对象作为具有默认值的模板,然后使用它来创建我可以自定义的新对象.对此最好的方法是什么?
谢谢!
这是我的javascript对象,我想知道如何避免在原型中多次使用"this".我知道有许多理论和原型关系的联系,这可能已经得到了解答,但由于我无法满足所有目的,我认为这可能值得另一个问题.
function shape(smth) {
this.a = smth
this.b = 2
this.c = 3
}
shape.prototype.doCalculus = function () {
return this.a * this.b + this.c - (2 * (this.b + this.c) + this.a);
}
module.exports = shape
Run Code Online (Sandbox Code Playgroud) 在控制台中运行以下代码时:
console.dir(document);
Run Code Online (Sandbox Code Playgroud)
在Chrome中,我看到了以下内容:
这似乎意味着该domain属性直接在document对象上.但事实并非如此.
console.log(document.hasOwnProperty('domain'));Run Code Online (Sandbox Code Playgroud)
在Chrome 72中,上升原型链,似乎是Document.prototype:
console.log(Document.prototype.hasOwnProperty('domain'));
console.log(Object.getOwnPropertyDescriptor(Document.prototype, 'domain'));Run Code Online (Sandbox Code Playgroud)
(在FF 56和其他一些浏览器中,它似乎是在开启HTMLDocument.prototype)
从片段中可以看出,该属性实际上由一个getter和一个setter组成.但是,我认为吸气剂在控制台中显示为(...),就像在此图像中一样,您必须单击它(...)来调用吸气剂.
如果我创建一个类似的对象,其原型包含getter/setter属性,并且我记录了该对象,则在检查时不会调用getter:
// look at results in Chrome's browser console, not snippet console
class theProto {
get foo() {
return 'fooVal';
}
set foo(arg) {
// do something
}
}
class theClass extends theProto {
}
const instance = new theClass();
console.dir(instance);Run Code Online (Sandbox Code Playgroud)
对于许多属性,可以看到相同的行为document.例如,您可以在第一个屏幕截图中看到的所有其他属性在其中一个原型对象上看起来都是getter/setter,而且它们都不在其中document:
console.log(
['dir', 'doctype', 'documentElement', 'documentURI', …Run Code Online (Sandbox Code Playgroud)javascript ×10
prototype ×4
ecmascript-6 ×2
inheritance ×2
console ×1
getter ×1
oop ×1
this ×1