一个jQuery面试题

面试题一览

代码如下

window.jQuery = ???
window.$ = jQuery

var $div = $('div')
$div.addClass('red') // 可将所有 div 的 class 添加一个 red
$div.setText('hi') // 可将所有 div 的 textContent 变为 hi

首先在 JSBbin 上写一个简单 html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div class="x">x</div>
<div class="x">x</div>
<div class="x">x</div>
</body>
</html>

然后 CSS 如下

.x.red {
border: 1px solid red;
}

初始效果图

坑一 (没 return 值)

首先手撸 js 代码如下

 window.jQuery = function(nodeOrSelector) {
let nodes = {};
if (typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSelector);
for (let i=0; i<temp.length; i++) {
nodes[i] = temp[i];
}
} else if ( nodeOrSelector instanceof Node ) {
nodes = {0: nodeOrSelector, length: 1};
}
nodes.addClass = function(classes) {
classes.forEach((value) => {
console.log(value);
for (let i=0; i < nodes.length; i++) {
nodes[i].classList.add(value);
};
});
};
};

window.$ = jQuery;

var $div = $('div');
$div.addClass('red'); // 可将所有 div 的 class 添加一个 red
$div.setText('hi'); // 可将所有 div 的 textContent 变为 hi

运行,但是出错

$div 未定义??? 很是奇怪,于是逐行屏蔽代码至如下

 window.jQuery = function(nodeOrSelector) {
let nodes = {};
console.log(nodeOrSelector);
// if (typeof nodeOrSelector === 'string') {
// let temp = document.querySelectorAll(nodeOrSelector);
// for (let i=0; i<temp.length; i++) {
// nodes[i] = temp[i];
// }
// } else if ( nodeOrSelector instanceof Node ) {
// nodes = {0: nodeOrSelector, length: 1};
// }
// nodes.addClass = function(classes) {
// classes.forEach((value) => {
// console.log(value);
// for (let i=0; i < nodes.length; i++) {
// nodes[i].classList.add(value);
// };
// });
// };
};

window.$ = jQuery;

var $div = $('div');
// $div.addClass('red'); // 可将所有 div 的 class 添加一个 red
// $div.setText('hi'); // 可将所有 div 的 textContent 变为 hi

打印出了 “div” ,说明函数的声明是没有问题的,想想是不是没有返回值,看了下构造函数果然没有,加返回解决,即

 window.jQuery = function(nodeOrSelector) {
let nodes = {};
if (typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSelector);
for (let i=0; i<temp.length; i++) {
nodes[i] = temp[i];
}
} else if ( nodeOrSelector instanceof Node ) {
nodes = {0: nodeOrSelector, length: 1};
}
nodes.addClass = function(classes) {
classes.forEach((value) => {
console.log(value);
for (let i=0; i < nodes.length; i++) {
nodes[i].classList.add(value);
};
});
};
return nodes;
};

window.$ = jQuery;

var $div = $('div');
$div.addClass('red'); // 可将所有 div 的 class 添加一个 red
// $div.setText('hi'); // 可将所有 div 的 textContent 变为 hi

坑二 (函数传参的判断)

然而这个时候报错

就很奇怪,打印一下 classes,结果是 ‘red’, 哦智障了,字符串哪里有 forEach 这个函数呢, Array 才有嘛,于是想到加一个判断转化

nodes.addClass = function(classes) {
if (typeof classes === 'string') {
let temp = classes;
classes = Array(temp);
}
classes.forEach((value) => {
for (let i=0; i < nodes.length; i++) {
nodes[i].classList.add(value);
};
});
};

问题解决

坑三 (没有 nodes.length)

想到应该可以了,运行代码发现 output 没变化,打开查看器看了下 html 源码发现没有把 ‘red’ 类加上去

说明是 addClass 函数的问题, console.log 一下 nodes.length 果然是 null,那么问题出在哪儿呢? 函数里声明的 nodes 应该是可以被访问到的,能被访问到为何没有 length ??? 看了下前面代码中

if (typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSelector);
for (let i=0; i<temp.length; i++) {
nodes[i] = temp[i];
}
}

哦懂了,temp 数组中的 length 没有复制过去, 加上 nodes.length = temp.length 即可

最终效果

最终代码如下

window.jQuery = function(nodeOrSelector) {
let nodes = {};
if (typeof nodeOrSelector === 'string') {
let temp = document.querySelectorAll(nodeOrSelector);
for (let i=0; i<temp.length; i++) {
nodes[i] = temp[i];
nodes.length = temp.length;
}
} else if ( nodeOrSelector instanceof Node ) {
nodes = {0: nodeOrSelector, length: 1};
}

nodes.addClass = function(classes) {
if (typeof classes === 'string') {
let temp = classes;
classes = Array(temp);
}
classes.forEach((value) => {
for (let i=0; i < nodes.length; i++) {
nodes[i].classList.add(value);
};
});
};

nodes.setText = function(text) {
for (let i=0; i<nodes.length; i++) {
nodes[i].textContent = text;
}
};

return nodes;
};

window.$ = jQuery;

var $div = $('div');
$div.addClass('red'); // 可将所有 div 的 class 添加一个 red
$div.setText('hi'); // 可将所有 div 的 textContent 变为 hi

output 效果如下

  • 添加 ‘red’

  • 将 textContent 变成 ‘hi’

点击这里预览