相当长的问题。但它基本上描述了我想要的内容。这里的代码用于创建任何对象according to user input
到输入文本字段。如果我想创建数字,字符串或对象,我只是必须在text field
中编写Number / String / Object。
引入了一个按钮来调用createObj.getObjName并从文本字段获取输入。它尝试匹配任何三种类型的对象(数字/字符串/对象)的输入。然后它调用一个bool函数 [problem lies here i think]
使用**list_keys array**
使用Array.prototype.some
进行迭代,assigned with objects
是使用包含不同对象名称的json对象创建的。new keyword
使用THIS keyword
创建
问题是调用检查功能我试图强迫 createObj
在其中指示 console.log(this)
对象而不是window object.I尝试过 input html button element
它为我提供了 <input type='button' id='btn' value="create">
的输出。
(function() {
var list = {
"Number": new Number(),
"String": new String(),
"Object": new Object(),
"Array": new Array()
}
var list_keys = Object.keys(list);
var createObj = {
re: null,
text: null,
match: null,
newObj: null,
getObjName: function() {
this.re = /Number|Object|String/;
this.text = document.getElementById('text').value;
this.match = this.text.match(this.re);
var bool = check.call(this);
if (bool) {
this.makeObj(list.this.match[0]);
}
},
makeObj: function(obj) {
this.newObj = obj;
}
};
function check() {
console.log(this);
return list_keys.some(function(el, indx, arr) {
return this.match[0] === el;
});
}
document.getElementById('btn').addEventListener('click', createObj.getObjName);
})();
但是我希望这可以引用createObj本身。为什么它指的是HTML元素?我该如何解决这个问题?
完整代码:
{{1}}
答案 0 :(得分:2)
你可以绑定对象,就像这样
createObj.getObjName.bind(createObj)
这将返回一个新功能,this
引用createObj
内的getObjName
。
此外,如果根本没有匹配怎么办?
return this.match[0] === el;
这会在运行时失败,因为this.match
将为null。所以你可能想做这样的事情
return this.match && list_keys.some(...);
如果我以更好的方式编写相同的代码,我会做这样的事情
(function() {
var MyObject = {
newObject: null,
createObject: function() {
var text = document.getElementById('text').value;
if (window.hasOwnProperty(text)) {
this.newObject = new window[text];
}
}
}
document.getElementById('btn').addEventListener('click',
MyObject.createObject.bind(MyObject));
})();
答案 1 :(得分:1)
将函数绑定到事件时,this
引用事件绑定的html节点。你可以通过各种方式解决这个问题。首先想到的是直接引用createObj
:
getObjName: function() {
createObj.re = /Number|Object|String/;
createObj.text = document.getElementById('text').value;
createObj.match = this.text.match(createObj.re);
var bool = check.call(createObj);
if (bool) {
this.makeObj(list.createObj.match[0]);
}
},
这不太理想,因为它通过名称引用对象,这意味着如果更改对象的名称,则必须更改对它的所有引用。如果您(或使用您的代码的其他开发人员)定义了新的createObj
,那么它也会出现问题。由于它是按名称引用对象,因此它将开始使用新声明的对象而不是您的对象。一个改进是为对象创建一个别名(通常称为该别名):
getObjName: function() {
that.re = /Number|Object|String/;
that.text = document.getElementById('text').value;
that.match = this.text.match(that.re);
var bool = check.call(that);
if (bool) {
this.makeObj(list.that.match[0]);
}
},
...
var that = createObj
问题在于that
通常意味着在上下文丢失的范围内引用this
,而不是任意对象(在这种情况下为createObj
)。
此外,我不确定该函数是否属于createObj
的方法,或者至少属于包含数据的结构。关注点的分离很重要,而
var createObj = {
re: null,
text: null,
match: null,
newObj: null,
关注您正在操纵的数据,getObjName
和makeObj
关注事件处理和使用收集的数据制作对象。我提取出一个结构来保存数据,然后我会在其他对象中使用它:
var descriptors = {
re: null,
text: null,
match: null,
newObj: null
}
var getObjName = function() {
descriptors.re = /Number|Object|String/;
descriptors.text = document.getElementById('text').value;
descriptors.match = descriptors.text.match(descriptors.re);
var bool = check.call(descriptors);
if (bool) {
makeObj(list.descriptors.match[0]);
}
}
var makeObj = function(obj) {
this.newObj = obj;
}
function check() {
console.log(this);
return list_keys.some(function(el, indx, arr) {
return this.match[0] === el;
});
}
document.getElementById('btn').addEventListener('click', getObjName);
这将结构与功能分开,更好地传达了部分的意图(descriptors
保存所有数据,getObjName
处理事件,makeObj
实例化新对象。
getObjName
违反了单一责任原则,但仍存在一个问题。它的任务是处理事件并获取对象的名称。我重构了事件处理部分,以保持getObjName
的意图:
var getObjName = function(descriptors) {
descriptors.re = /Number|Object|String/;
descriptors.text = document.getElementById('text').value;
descriptors.match = this.text.match(descriptors.re);
return check.call(descriptors);
}
document.getElementById('btn').addEventListener('click', function() {
if (getObjName(descriptors)) {
makeObj(list.descriptors.match[0]);
}
});