有没有更好的方法来编写这个而不是编写四个基本相同的函数?我怎么能调用相同的函数,但使用该函数显示同一对象的不同属性。
在以下示例中,a
是“paragraph”元素。
事件监听器与“输入”元素绑定,类型为按钮。
function $(id){
return document.querySelector(id);
};
function Person(name, age, weight, favoriteActivity) {
this.name = name;
this.age = age;
this.weight = weight;
this.favoriteActivity = favoriteActivity;
}
var Jack = new Person("Jack Crish", 29, 200, "coding");
var a = document.querySelector("#person");
function showAge(){
a.innerHTML = Jack.age;
}
function showName(){
a.innerHTML = Jack.name;
}
function showWeight(){
a.innerHTML = Jack.weight;
}
function showActivity(){
a.innerHTML = Jack.favoriteActivity;
}
$("#age").addEventListener("click", showAge);
$("#name").addEventListener("click", showName);
$("#weight").addEventListener("click", showWeight);
$("#enjoys").addEventListener("click", showActivity);
JSFiddle在这里找到:http://jsfiddle.net/metkjnyn/
答案 0 :(得分:2)
当然,只需让函数接受一个指示要显示的属性的参数。
function $(id){
return document.querySelector(id);
};
function Person(name, age, weight, favoriteActivity) {
this.name = name;
this.age = age;
this.weight = weight;
this.favoriteActivity = favoriteActivity;
}
var Jack = new Person("Jack Crish", 29, 200, "coding");
var a = $("#person");
function showProperty(property) {
this.innerHTML = Jack[property];
}
/*
function showAge(){
a.innerHTML = Jack.age;
}
function showName(){
a.innerHTML = Jack.name;
}
function showWeight(){
a.innerHTML = Jack.weight;
}
function showActivity(){
a.innerHTML = Jack.favoriteActivity;
}
*/
$("#age").addEventListener("click", showProperty.bind(a, 'age'));
$("#name").addEventListener("click", showProperty.bind(a, 'name'));
$("#weight").addEventListener("click", showProperty.bind(a, 'weight'));
$("#enjoys").addEventListener("click", showProperty.bind(a, 'favoriteActivity'));
p{
width:200px;
height:20px;
border:1px solid grey;
}
<p id ="person"></p>
<input id ="age" type = "button" value = "age"></input>
<input id ="name" type = "button" value = "name"></input>
<input id ="weight" type = "button" value = "weight"></input>
<input id ="enjoys" type = "button" value = "enjoys"></input>
答案 1 :(得分:1)
由于对象属性可以作为字符串索引访问,并且基于元素的ID正是属性名称这一事实,您可以使用事件调用者的id引用作为要更改的属性:
function show() {
a.innerHTML = Jack[this.id];
}
$("#age").addEventListener("click", show);
$("#name").addEventListener("click", show);
$("#weight").addEventListener("click", show);
$("#enjoys").addEventListener("click", show);
修改强>
正如Kevin B所指出的,你需要它们将 enjoy id与实际的属性名称相匹配,例如:
http://jsfiddle.net/metkjnyn/4/
<input id ="favoriteActivity" type = "button" value = "enjoys"></input>
$("#favoriteActivity").addEventListener("click", show);
答案 2 :(得分:1)
有,但他们也更糟。例如:
function Person(...) { ...; this.setup(); };
Person.prototype = {
setup: function() {
var self = this;
['name','age','weight','activity'].forEach(function(propName) {
var fname = "show"+propName;
self[fname] = function() { return self[propName]; }
document.getElementById(propName).addEventListener("click", self[fname]);
});
}
};
更好吗?嗯,是的,不。它更简洁,可以出错的代码更少,因为它没有重复,但现在你有一个需要更新的硬编码属性列表,你的对象的API就像泥一样透明(你现在必须分析代码到找出你的Person对象有哪些功能。)
最佳做法是使用易于阅读的API使对象透明:
function Person(name, age, weight, favoriteActivity) {
this.name = name;
this.age = age;
this.weight = weight;
this.favoriteActivity = favoriteActivity;
}
Person.prototype = {
showAge: function(evt){
evt.target.textContent = this.age;
},
showName: function(evt){
evt.target.textContent = this.name;
},
showWeight: function(evt){
evt.target.textContent = this.weight;
},
showActivity: function(evt){
evt.target.textContent = this.favoriteActivity;
},
bindToElement: function(a){
a.querySelector(".name").addEventListener("click", this.showAge);
a.querySelector(".age").addEventListener("click", this.showName);
a.querySelector(".weight").addEventListener("click", this.showWeight);
a.querySelector(".fav").addEventListener("click", this.showActivity);
}
};
然后有一些单独的代码来初始化人员:
function makePerson(name) {
var person = new Person(name);
var el = document.querySelector("....");
person.bindToElement(el);
}
...
makePerson("Jack");
并尝试远离那些id
选择器。它们是确保您无法在页面上添加其他内容的绝佳方式。
答案 3 :(得分:0)
在JavaScript中,您可以通过Jack.name
格式以及Jack['name']
格式访问对象的属性。因此,如果您在每个函数中执行的操作都是访问给定对象的属性,则可以创建一个名为showInfo
的函数,该函数将获取您要访问的属性的名称:
function showInfo(field) {
a.innerHtml = Jack[field];
}
这样,调用showInfo('name')
将与调用showName()相同。然后,您可以让每个侦听器将字符串传递给同一个函数 - 甚至可以根据按钮的ID确定这些字符串。希望这能指导您更好地减少代码重复。
答案 4 :(得分:0)
添加&#34; get&#34;你的Person.prototype的方法
Person.prototype.get = function (p) {
a.innerHTML = this[p];
}
并在eventListener中调用它
$("input").addEventListener("click", function() {Jack.get(this.value);});
$("#name").addEventListener("click", function() {Jack.get(this.value);});
$("#weight").addEventListener("click", function() {Jack.get(this.value);});
$("#enjoys").addEventListener("click", function() {Jack.get(this.value);});
答案 5 :(得分:0)
您可以创建一个执行事件绑定的函数,并一次指定哪个属性:
function showProperty(id, property) {
$("#" + id).addEventListener("click", function(e) {
a.innerHTML = Jack[property];
});
}
showProperty("age", "age");
showProperty("name", "name");
showProperty("weight", "weight");
showProperty("enjoys", "favoriteActivity");
或者,您可以采用更具说明性的方法,并从按钮推断属性。这需要在enjoys
按钮中添加属性:
<input type="button" value="enjoys" data-property="favoriteActivity" />
function showProperty(e) {
var property = this.getAttribute("data-property") || this.value;
a.innerHTML = Jack[property];
}
var buttons = document.querySelectorAll("input[type=button]");
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", showProperty);
}
两者都比原来干得多。