var el = {
'btn1': '#btn',
'time1': '#time',
'audio': 'audio',
'elem': '.elem'
}
new Function()
将键作为变量名,然后将值分配给它们apply()
,bind()
将变量传递给函数问题是
apply()
,bind()
将变量设置为 window 对象以使其成为全局变量,我希望它们成为此函数的局部变量function selectElements(obj, fn) {
if (typeof fn === 'function') {
for(var i in obj) {
obj[i] = obj[i].replace(/^\#/, function(selectedElem) {
selectedElem = obj[i].replace(/^\#/, '');
new Function('return '+ fn+'.bind('+i+' = document.getElementById("'+selectedElem+'"))')()
}).replace(/^\./, function(selectedElem) {
selectedElem = obj[i].replace(/^\./, '');
new Function('return '+ fn+'.bind('+i+' = document.getElementsByClassName("'+selectedElem+'"))')()
}).replace(/^\w+/, function(selectedElem) {
if (!selectedElem.startsWith('undefined')) {
new Function('return '+ fn +'.bind('+i+' = document.getElementsByTagName("'+selectedElem+'"))')()
}
})
}
}
}
function selectElements(obj, fn) {
fn.bind(x = 123)
}
fn
not 到 window 对象完整代码
var el = {
'btn1': '#btn',
'time1': '#time',
'audio': 'audio',
'elem': '.elem'
}
function selectElements(obj, fn) {
var sel;
if (typeof fn === 'function') {
for (var i in obj) {
obj[i] = obj[i].replace(/^\#/, function(selectedElem) {
selectedElem = obj[i].replace(/^\#/, '');
sel = ' = document.getElementById("' + selectedElem + '")'
new Function('return ' + fn + '.bind(' + i + sel + ')')()
}).replace(/^\./, function(selectedElem) {
selectedElem = obj[i].replace(/^\./, '');
sel = ' = document.getElementsByClassName("' + selectedElem + '")'
new Function('return ' + fn + '.bind(' + i + sel + ')')()
}).replace(/^\w+/, function(selectedElem) {
if (!selectedElem.startsWith('undefined')) {
sel = ' = document.getElementsByTagName("' + selectedElem + '")'
new Function('return ' + fn + '.bind(' + i + sel + ')')()
}
})
}
fn()
}
}
selectElements(el, function() {
console.log(window)
console.log(btn1, time1, audio, elem)
})
<div id="time"></div>
<audio controls src="audio.mp3" type="audio/mpeg"></audio>
<button id="btn">play</button>
<div class="elem">000</div>
我认为你能做到的唯一方法是在函数本身内并通过邪恶eval()
......
var el = {
'btn1': '#btn',
'time1': '#time',
'audio': 'audio',
'elem': '.elem'
}
function selectElements(obj, fn) {
if (typeof fn === 'function') {
const that = {};
for (let i in obj)
that[i] = document["querySelector" + (obj[i][0] == "#" ? "" : "All")](obj[i]);
return fn.bind(that)();
}
}
selectElements(el, function() {
for(let i in this)
{
let t = this[i];
eval("var " + i + "=t");
}
console.log("global", window.btn1, window.time1, window.audio, window.elem);
console.log("local", btn1, time1, audio, elem)
console.log("this", this.btn1, this.time1, this.audio, this.elem)
})
<div id="time"></div>
<audio controls src="audio.mp3" type="audio/mpeg"></audio>
<button id="btn">play</button>
<div class="elem">000</div>
或者通过非常“hacky”的方式重新创建回调函数向其添加参数变量,但它存在范围问题:
var el = {
'btn1': '#btn',
'time1': '#time',
'audio': 'audio',
'elem': '.elem'
}
function selectElements(obj, fn) {
if (typeof fn === 'function') {
const that = {};
for (let i in obj)
that[i] = document["querySelector" + (obj[i][0] == "#" ? "" : "All")](obj[i]);
let f = fn.toString();
return new Function(...Object.keys(that), f.slice(f.indexOf("{") + 1, f.lastIndexOf("}"))).apply(null, Object.values(that));
}
}
selectElements(el, function() {
console.log("global", window.btn1, window.time1, window.audio, window.elem);
console.log("local", btn1, time1, audio, elem)
console.log("this", this.btn1, this.time1, this.audio, this.elem)
})
//this doesn't work, because callback function will be recreated in different scope
for(let i = 0; i < 3; i++)
{
selectElements(el, function()
{
console.log(i);
console.log(btn1);
});
}
<div id="time"></div>
<audio controls src="audio.mp3" type="audio/mpeg"></audio>
<button id="btn">play</button>
<div class="elem">000</div>
虽然我不会推荐任何这些方法......
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句