1
(window.foo || (window.foo = “bar”));
document.write(foo);
//输出
//bar;
//括号优先级最高 先执行括号里面的内容(window.foo = “bar”) 此时foo为bar
//再执行window.foo 这个没什么意义 所以最终得到foo为bar
//这题如果这样写(window.foo || window.foo = “bar”) 会报错
//因为 || 运算级比 == 高
2 (阿里笔试题)
function test(a,b,c,d){
console.log(a+b+c+d);
}(1,2,3,4);
//按理说这样写会报错
//但是系统识别时 会让其尽量不报错
//所以系统是这样识别的
function test(a,b,c,d){
console.log(a+b+c+d);
}
(1,2,3,4);
//即把 函数 和 (1,2,3,4); 分开 所以此时函数也不执行 系统也不报错
*3(常见)
3.1
![@RY6Q6C(B29)({A4MYCR9W.png
//注意这里只是把function装进了arr[i]中 系统并不管function中写了什么 只有当function执行时才会读里面的语句
//也就是函数定义时并不用看函数里面有什么 只有当函数执行时才知道里面是什么
//test执行完后 将arr返回出去给了myArr
//此时arr中共装有10个function 这10个function都产生了闭包
//遍历执行myArr[j]函数 即执行arr[j]函数
//但是arr[j]中装的是输出i 从作用域链上至下寻找变量i 此时i的值为10
//所以输出结果为10个10
//也就是说函数中的语句不是定义之后就执行的 是等到函数被调用时才会执行
//即上述的那个function里面的语句不是定义时就把i装进去了 而是等到被调用时才知道i是几
3.2
若想按顺序输出,解决方法:
//上述for循环产生了10个不同的立即执行函数 它们彼此独立
//每个arr[j]保存的是相对应的立即执行函数的劳动成果(即执行期上下文)
//然后arr被返回出去给了myArr 当myArrj执行时 即对应arr[j]执行
//然后arr[j]执行时需要找j 自己这没有 就找立即执行函数中的j 发现立即执行函数的j被i传参了
//比如 (function (j) {
arr[j] = function () {
console.log(j);
}
}(0))
//此时 i = 0传给了j 所以j = 0 以此类推 所以这时就可以按顺序输出了
4
//看括号 发现里面有逗号 那么把最后一个返回
//括号中只剩最后一个函数
//即 function g() {
return 2;
}
//所以结果为 var f = 2; 即为number类型
5
//if()的括号中写的是条件 而被认定为false的只有那六个 所以这里一定能执行
//(function f(){}) 括号把这个函数变为表达式了 那么这个就不是函数定义了
//既然不是函数定义 那么系统中就不存在这个函数f
//本来任何一个变量未经声明就使用会报错 但是typeof是个例外
//所以即使f不存在 也能返回string类型的undefined
//那么结果就是 1undefined
6
//输出
//string;
//undefined;
7
构造一个函数 计算字符串的字节长度 code码大于255之后是中文 中文占两个字节
8 区别对象和数组的三种方法
1 constructor
[].constructor —-> Array
var obj = {}; obj.constructor —-> Object
2 instanceof
[] ininstanceof Array —->true
obj ininstanceof Array —->false
*3 Object.prototype.toString.call( )
Object.prototype.toString.call( [] ) —-> “[object Array]”
Object.prototype.toString.call( {} ) —-> “[object Object]”
9
function test(){
test1.apply(null,arguments);
}
function test1(){
console.log(arguments);
}
test(1,2,3,4,5);
//结果输出一个数组 [1,2,3,4,5]
10 this
//结果为
// 222
// 111
// 222
// 333
11 this
11.1
//注意此时print是一个函数 不是对象 所以this指代的是window
//print函数自身没有foo 所以就上GO里面去找 this.foo就改变了window的foo
//所以输出 234
11.2
//注意此时print是一个对象 所以this指代就不是window了 指代的是print对象
//即 this.foo = 234; 就把 234 装到了这个this对象中
//那么此时访问的是foo 但不是this上的foo 但是print对象AO中没有foo 所以只能去全局中找
//输出 123
11.3
//输出 0 5 0 0 undefined 0
//对于new test(); 其AO为
// AO{
// a : 0
// this : { proto : test.prototype }
// }
//所以输出 this.a 时 因为this中没有a 所以输出 undefined
12
//haha没有定义直接使用 程序报错 error : haha is not defined
13 克隆 将一个对象克隆给另外一个对象 且两者之间没有关联
1 判断是不是原始值
2 判断是数组还是对象
3 建立对应的数组或对象
var deepClone = function(origin,target){
//如果没有传递target参数 那么我们就可以人为帮它创建一个空对象
var target = target || {};
toStr = Object.prototype.toString;
arrStr = '[Object Array]';
for(var value in origin){
//先判断属性是不是自己的
if(origin.hasOwnProperty(value)){
//判断属性是不是原始值 若不是 且属性不为null(因为null的类型也是object)
if(origin[value]!=='null' && typeof(origin[value]) == 'object'){
//判断是数组还是对象
//这里也可以用三目运算符
//
if(toStr.call(origin[value]) == arrStr){
//数组
target[value] = [];
}else{
//对象
target[value] = {};
}
//递归执行数组或对象里面的克隆
deepClone(origin[value],target[value]);
}else{
//若属性是原始值 那么就可以直接赋值
target[value] = origin[value];
}
}
}
return target;
}
14 给定一个有序数组 让其乱序排列
var arr = [1,2,3,4,5,6,7];
arr.sort(function(){
return Math.random()-0.5;
});
//Math.random()产生的是(0,1)之间的数
15 封装typeof方法
<script>
var type = function(target){
var template = {
'[object Array]' : 'array',
'[object Number]' : 'number-object',
'[object Object]' : 'object',
'[object Boolean]' : 'boolean-object',
'[object String]' : 'string-object',
}
//判断target是否为null 注意这里是绝对等于 因为undefined==null 比较结果也是true
if(target === null){
return 'null';
}
//判断是否是原始值 或 引用
if(typeof target == 'object'){
var str = Object.prototype.toString.call(target);
return template[str];
}else{
//是原始值 或 函数 都直接返回
return typeof target;
}
}
</script>
16 数组去重
<script>
Array.prototype.unique = function(){
//temp用来去重
//finalArr用来存储最终去重后的数组
var temp = {},
finalArr = [],
len = this.length;
for(var i = 0; i<len; i++){
//
if(!temp[this[i]]){
//将数组的值作为temp对象的属性名 如果属性名已经存在了 就不往里存东西
//属性值这里取值为abc
//注意属性值不能取为false的值 以及this[i]
//因为执行判断时 会导致判断结果为true 就达不到去重的效果
//如 temp[this[i]] = this[i] 当存 0 时 判断if(!temp[this[i]])
//结果为true 执行finalArr.push(this[i]);
//那么后续存 0 时 仍然会把0装进finalArr数组中
temp[this[i]] = 'abc';
finalArr.push(this[i]);
}
}
return finalArr;
}
</script>
比如
var arr = [2,2,2,1,3,1,3,5,2,4,5,5,]
arr.unique();
//结果为[2, 1, 3, 5, 4]
17 返回元素e的第n层祖先元素节点
<script>
function retParent(elem,n){
while(elem && n){
elem = elem.parentElement;
n--;
}
return elem;
}
</script>
18 封装myChildren功能 解决部分浏览器不兼容问题
<script>
Element.prototype.myChilden = function(){
var child = this.childNodes,
len = child.length,
arr = [];
for(var i = 0;i<len;i++){
if(child[i].nodeType == 1){
arr.push(child[i])
}
}
return arr;
}
</script>
19 封装函数 输入元素elem和位数n 若n为正数 返回元素elem后面的第n位兄弟元素
若n为负数 返回元素elem前面的第n位兄弟元素 若n为0 返回自己
<script>
function retSibling(elem, n) {
while (elem && n) {
if (n > 0) {
//这里是为了IE浏览器的兼容问题 不兼容就走下面的else
if (elem.nextElementSibling) {
elem = elem.nextElementSibling;
} else {
for (elem = elem.nextSibling; elem && elem.nodeType != 1; elem = elem.nextSibling) { };
}
n--;
} else {
if (elem.previousElementSibling) {
elem = elem.previousElementSibling;
} else {
for (elem = elem.previousSibling; elem && elem.nodeType != 1; elem = elem.previousSibling) { };
}
n++;
}
}
return elem;
}
</script>
20 模拟insertBefore函数 封装insertAfter函数
//方式一
<script>
Element.prototype.insertAfter = function(newTag, tag) {
this.replaceChild(newTag, tag);
this.insertBefore(tag, newTag);
}
</script>
//方式二
<script>
Element.prototype.insertAfter = function(targetNode, afterNode) {
var beforeNode = afterNode.nextElementSibling;
if(beforeNode == null){
this.appendChild(targetNode);
}else{
this.insertBefore(targetNode,beforeNode);
}
}
</script>
21 使用JS的addEventListener 给每一个li绑定一个click事件 要求输出他们的次序
- a
- a
- a
- a
即点击第一个li输出1 点第二个li输出2 以此类推
<script>
var li = document.getElementsByTagName('li');
len = li.length;
for (var i = 0; i < len; i++) {
//注意闭包就要用到这个立即执行函数
(function(j){
li[j].addEventListener('click',function(){
console.log(j+1);
},false)
}(i))
}
</script>
22 ** 应用 mousedown mousemove mouseup 实现鼠标拖拽应用 可以随机移动方块**
<body>
//注意要写为行间样式 若写为外部样式 那么不好用
<div style=" width: 100px;height: 100px;background-color: green;position: absolute;
left: 0;top: 0;"></div>
<script>
var div = document.getElementsByTagName('div')[0];
var disX,
disY;
div.onmousemove = function (e) {
disX = e.pageX - parseInt(div.style.left),
disY = e.pageY - parseInt(div.style.top);
document.onmousemove = function (e) {
div.style.left = e.pageX - disX + 'px';
div.style.top = e.pageY - disY + 'px';
}
document.onmouseup = function(){
div.onmousemove = null;
}
}
</script>
</body>
封装后的drag函数 可以拖拽任意元素
<body>
<div style=" width: 100px;height: 100px;background-color: green;position: absolute;
left: 0;top: 0;"></div>
<script>
var div = document.getElementsByTagName('div')[0];
drag(div);
function drag(elem) {
var disX,
disY;
addEvent(elem, 'mousedown', function (e) {
var event = e || window.event;
//disX和disY表示鼠标位置距离元素区域左侧和上侧的距离
disX = event.pageX - parseInt(getStyle(elem, 'left')),
disY = event.pageY - parseInt(getStyle(elem, 'top'));
//mousemove和mouseup如果绑定在元素身上 那么当鼠标移动过快导致移出元素区域时
//那么因为监听事件间隔时间可能没那么快 就会导致元素定着不动 即使我们没有松开鼠标按键
//所以事件可以绑定在document身上 这时无论鼠标怎么移动 元素都会跟着
addEvent(document, 'mousemove', mouseMove);
addEvent(document,'mouseup',mouseUp);
});
function mouseMove(e) {
var event = e || window.event;
//要想元素随鼠标移动 就需要改变其坐标
elem.style.left = event.pageX - disX + 'px';
elem.style.top = event.pageY - disY + 'px';
}
function mouseUp(e){
document.removeEventListener('mousemove',mouseMove,false);
}
}
function addEvent(elem, type, handleFunc) {
if (elem.addEventListener) {
elem.addEventListener(type, handleFunc, false);
} else if (elem.attachEvent) {
elem.attachEvent('on' + type, function () {
handleFunc.call(elem);
})
} else {
elem['on' + type] = handleFunc;
}
}
function getStyle(elem, prop) {
if (window.getComputedStyle) {
return window.getComputedStyle(elem, null)[prop];
} else {
return elem.currentStyle[prop];
}
}
</script>
</body>
23 检测字符串是否首尾是否含有数字
即判断首或尾是否有数字
var reg = /^\d|\d$/g;
若判断首尾都是否有数字
var reg = /^\d[\s\S]\d$/g; 这里中间些什么区间都行 不过要写成全集的这种形式
24 (百度笔试)
让一个数从后往前 每隔三个位置写一个小数点
如 100000000 —-> 100.000.000
<script>
//首先要从尾部开始往前找 所以用到了$
//三位数字为一组 所以用到了(\d{3})
//每三位数字一组 往前匹配 所以是(\d{3})+$)
//如果匹配完前面刚好剩三个 那么最前面也会加上小数点. 所以我们要加上非单词边界\B
//即匹配的三位数 要是非单词边界 才会加小数点.
//其中 (?=n)前面未写 那么就为空 即匹配空后紧接指定字符串 n 的字符串
//所以 (?=(\B)(\d{3})+$) 就表示 匹配空后 紧接指定的 非单词边界 且 从后往前每三位数字一组的 字符串
var reg = /(?=(\B)(\d{3})+$)/g;
var str = "100000000";
console.log(str.replace(reg,"."));
</script>