JavaScript: 如何在原型中使用方法?
JavaScript: How to use a method within a prototype?
我正在尝试修改一个插件 (Pikaday) 并添加我自己的一点点功能。
该插件是使用原型系统构建的,我在其中添加了我的功能。
Pikaday.prototype = {
//OTHER PARTS OF PLUGIN
showYearPicker: function()
{
document.getElementsByClassName('pika-year-label').onclick=function(){
console.log("asfd");
}
},
//OTHER PARTS OF PLUGIN
}
return Pikaday;
我无法理解的是如何实际触发此方法。单击指定元素无效。
有人知道我如何将此功能作为插件的一部分吗?
如果有人感兴趣,Full code(减去我的补充)就在这里。
简单来说,在函数原型上定义一个方法意味着您已经在一个对象上定义了一个方法,该对象将是该函数所有实例的原型链上游link。
您可以将其视为该函数的每个实例的通用 "parent" 或 "object-above"。
因此,要使用您的方法,您必须实例化插件并在其上调用您的函数。
function Pikaday() {}
Pikaday.prototype = {
showYearPicker: function() {
console.log('called');
}
}
let pikaday = new Pikaday();
pikaday.showYearPicker(); // <-- call the function on the prototype
这将做的是检查 pikaday
是否定义了 showYearPicker
,因为它没有,它会上升到原型链并检查该对象是否有它,这确实如此。
换句话说,这本质上就是JS引擎在幕后所做的事情:
let pikaday = new Pikaday();
pikaday.__proto__.showYearPicker();
请注意 proto here is just for demonstration, its only recently been standardized in ES6 for legacy purposes, but this behavior should be left to the JS engine (The spec 调用此原型 link [[Prototype]]
)。
如果需要,访问原型的正确方法是使用 Object.getPrototypeOf (in +ES6 you could use the semantically-clearer Reflect.getPrototypeOf)
function Pikaday() {}
console.log(
Object.getPrototypeOf(new Pikaday()) === Pikaday.prototype
);
console.log(
Reflect.getPrototypeOf(new Pikaday()) === Pikaday.prototype
);
您的代码的一个问题是 getElementsByClassName will return a NodeList(不是数组)具有此 class.
的节点
这意味着您必须遍历此列表并为每个元素附加一个处理程序,
let nodes = document.getElementsByClassName('pika-year-label');
Array.from(nodes) // convert NodeList to an array so we can use forEach
.forEach(node => {
// attach a handler on each node
node.onclick = function (){
console.log("asfd");
}
});
// Side Note: You can also use array spread to convert the node list to an array
// [...nodes].forEach( ... )
或者将处理程序附加到所有元素的公共父级以委托行为。
document.body.onclick = function(e) {
if (e.target.classList.contains('pika-year-label')) {
console.log("asfd");
}
}
最后,如果您只想将此函数添加到现有函数的原型中,一种方法是简单地将其定义为该原型上的方法:
function Pikaday() {}
// define a method on the existing prototype
Pikaday.prototype.showYearPicker = function() {
console.log('called');
};
let pikaday = new Pikaday();
pikaday.showYearPicker(); // <-- call the function on the prototype
我正在尝试修改一个插件 (Pikaday) 并添加我自己的一点点功能。
该插件是使用原型系统构建的,我在其中添加了我的功能。
Pikaday.prototype = {
//OTHER PARTS OF PLUGIN
showYearPicker: function()
{
document.getElementsByClassName('pika-year-label').onclick=function(){
console.log("asfd");
}
},
//OTHER PARTS OF PLUGIN
}
return Pikaday;
我无法理解的是如何实际触发此方法。单击指定元素无效。
有人知道我如何将此功能作为插件的一部分吗?
如果有人感兴趣,Full code(减去我的补充)就在这里。
简单来说,在函数原型上定义一个方法意味着您已经在一个对象上定义了一个方法,该对象将是该函数所有实例的原型链上游link。
您可以将其视为该函数的每个实例的通用 "parent" 或 "object-above"。
因此,要使用您的方法,您必须实例化插件并在其上调用您的函数。
function Pikaday() {}
Pikaday.prototype = {
showYearPicker: function() {
console.log('called');
}
}
let pikaday = new Pikaday();
pikaday.showYearPicker(); // <-- call the function on the prototype
这将做的是检查 pikaday
是否定义了 showYearPicker
,因为它没有,它会上升到原型链并检查该对象是否有它,这确实如此。
换句话说,这本质上就是JS引擎在幕后所做的事情:
let pikaday = new Pikaday();
pikaday.__proto__.showYearPicker();
请注意 proto here is just for demonstration, its only recently been standardized in ES6 for legacy purposes, but this behavior should be left to the JS engine (The spec 调用此原型 link [[Prototype]]
)。
如果需要,访问原型的正确方法是使用 Object.getPrototypeOf (in +ES6 you could use the semantically-clearer Reflect.getPrototypeOf)
function Pikaday() {}
console.log(
Object.getPrototypeOf(new Pikaday()) === Pikaday.prototype
);
console.log(
Reflect.getPrototypeOf(new Pikaday()) === Pikaday.prototype
);
您的代码的一个问题是 getElementsByClassName will return a NodeList(不是数组)具有此 class.
的节点这意味着您必须遍历此列表并为每个元素附加一个处理程序,
let nodes = document.getElementsByClassName('pika-year-label');
Array.from(nodes) // convert NodeList to an array so we can use forEach
.forEach(node => {
// attach a handler on each node
node.onclick = function (){
console.log("asfd");
}
});
// Side Note: You can also use array spread to convert the node list to an array
// [...nodes].forEach( ... )
或者将处理程序附加到所有元素的公共父级以委托行为。
document.body.onclick = function(e) {
if (e.target.classList.contains('pika-year-label')) {
console.log("asfd");
}
}
最后,如果您只想将此函数添加到现有函数的原型中,一种方法是简单地将其定义为该原型上的方法:
function Pikaday() {}
// define a method on the existing prototype
Pikaday.prototype.showYearPicker = function() {
console.log('called');
};
let pikaday = new Pikaday();
pikaday.showYearPicker(); // <-- call the function on the prototype