0%

JavaScript 记录

Js

##算法

循环数组的数组

1
2
3
4
5
6
7
8
9
10
11
function loop(arr) {
if (arr && arr.length <= 1) return arr[0];
var temA = [];
for (var i = 0, len1 = arr[0].length; i < len1; i++) {
for (var j = 0, len2 = arr[1].length; j < len2; j++) {
temA.push(arr[0][i] + '&' + arr[1][j]);
}
}
arr = [temA].concat(arr.splice(2));
return arguments.callee(arr);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var arr=[];
var arr1=[1,2,3];
var arr2=[4,5,6];
arr.push(arr1);
arr.push(arr2);

loop(arr);

结果:["1&4", "1&5", "1&6", "2&4", "2&5", "2&6", "3&4", "3&5", "3&6"]

var arr3=[7,8,9];
arr.push(arr3);
loop(arr);

结果:["1&4&7", "1&4&8", "1&4&9", "1&5&7", "1&5&8", "1&5&9", "1&6&7", "1&6&8", "1&6&9", "2&4&7", "2&4&8", "2&4&9", "2&5&7", "2&5&8", "2&5&9", "2&6&7", "2&6&8", "2&6&9", "3&4&7", "3&4&8", "3&4&9", "3&5&7", "3&5&8", "3&5&9", "3&6&7", "3&6&8", "3&6&9"]

两个数组比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var arr1=[1,2,3];
var arr2=[1,3,5];
var end = arr1.length;
var swap = false;
for (var i = 0; i < end;) {
swap = false;
for (var j = i; j < arr2.length; j++) {
if (arr1[i] == arr2[j]) {
var tmp = arr2[i];
arr2[i] = arr2[j];
arr2[j] = tmp;
swap = true;
break;
}
}
if (swap != true) {
var tmp = arr1[i];
arr1[i] = arr1[--end];
arr1[end] = tmp;
} else {
i++;
}
}

结果: end 之前是相同的元素,end 之后是不同的元素
如果 end == arr1.length && end == arr2.length,两个数组的值一样

JS call 方法

call 主要改变了 this 的指向

1
2
3
4
5
6
var a = function(){
console.log(this); // 'littledu'
console.log(typeof this); // Object
console.log(this instanceof String); // true
}
a.call('littledu');

call 了后,就把当前函数推入所传参数的作用域中去了,不知道这样说对不对,但反正 this 就指向了所传进去的对象就肯定的了。

Array.prototype.slice.call(arguments)

Array.prototype.slice.call(arguments)能将具有 length 属性的对象转成数组,除了 IE 下的节点集合(因为 ie 下的 dom 对象是以 com 对象的形式实现的,js 对象与 com 对象不能进行转换)

1
2
3
4
5
var a={length:2,0:'first',1:'second'};
Array.prototype.slice.call(a);// ["first", "second"]

var a={length:2};
Array.prototype.slice.call(a);// [undefined, undefined]

Jquery

attr()和 prop()

https://segmentfault.com/a/1190000002680303

取数据的时候用到了以前都没用过的$(this).data('xxx')的这种形式,后来看了手册才知道在 HTML5 中可以对元素进行自定义属性。格式类似于data-xxx="value",然后可以用 JQ 中的.data()方法进行存取数据。

操作对象不同

在 jQuery 中 attr 表示 HTML 文档节点属性,而 prop 则表示 JS 对象属性。

1
2
3
4
5
6
7
<!-- 这里的id、class、data_id均是该元素文档节点的attribute -->
<div id="message" class="test" data_id="123"></div>

<script type="text/javascript">
// 这里的name、age、url均是obj的property
var obj = { name: 'CodePlayer', age: 18, url: 'https://www.365mini.com/' };
</script>

在 jQuery 中,prop()函数的设计目标是用于设置或获取指定 DOM 元素(指的是 JS 对象,Element 类型)上的属性(property);attr()函数的设计目标是用于设置或获取指定 DOM 元素所对应的文档节点上的属性(attribute)。

1
2
3
4
5
6
7
8
9
<!-- attr()函数针对的是该文档节点的attribute -->

<div id="message" class="test" data_id="123"></div>

<script type="text/javascript">
// prop()函数针对的是该DOM元素(msg)自身的property
var msg = document.getElementById('message');
var $msg = $(msg);
</script>

当然,在 jQuery 的底层实现中,函数attr()prop()的功能都是通过 JS 原生的 Element 对象(如上述代码中的 msg)实现的。attr()函数主要依赖的是 Element 对象的 getAttribute()和 setAttribute()两个方法。prop()函数主要依赖的则是 JS 中原生的对象属性获取和设置方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="message" class="test" data_id="123"></div>

<script type="text/javascript">
var msg = document.getElementById('message');
var $msg = $(msg);

/* *** attr()依赖的是Element对象的element.getAttribute( attribute ) 和 element.setAttribute( attribute, value ) *** */

// 相当于 msg.setAttribute("data_id", 145);
$msg.attr('data_id', 145);

// 相当于 msg.getAttribute("data_id");
var dataId = $msg.attr('data_id'); // 145

/* *** prop()依赖的是JS原生的 element[property] 和 element[property] = value; *** */

// 相当于 msg["pid"] = "pid值";
$msg.prop('pid', 'pid值');

// 相当于 msg["pid"];
var testProp = $msg.prop('pid'); // pid值
</script>

当然,jQuery 对这些操作方式进行了封装,使我们操作起来更加方便(比如以对象形式同时设置多个属性),并且实现了跨浏览器兼容。

此外,虽然prop()针对的是 DOM 元素的property,而不是元素节点的attribute。不过 DOM 元素某些属性的更改也会影响到元素节点上对应的属性。例如,property 的 id 对应 attribute 的 id,property 的 className 对应 attribute 的 class。

1
2
3
4
5
6
7
8
9
10
11
<div id="message" class="test" data_id="123"></div>

<script type="text/javascript">
var msg = document.getElementById('message');
var $msg = $(msg);

document.writeln($msg.attr('class')); // test
$msg.prop('className', 'newTest');
// 修改className(property)导致class(attitude)也随之更改
document.writeln($msg.attr('class')); // newTest
</script>

应用版本不同

attr()是 jQuery 1.0 版本就有的函数,prop()jQuery 1.6版本新增的函数。毫无疑问,在 1.6 之前,你只能使用attr()函数;1.6 及以后版本,你可以根据实际需要选择对应的函数。

设置属性值类型不同

由于 attr()函数操作的是文档节点的属性,因此设置的属性值只能是字符串类型,如果不是字符串类型,也会调用其 toString()方法,将其转为字符串类型。
prop()函数操作的是 JS 对象的属性,因此设置的属性值可以为包括数组和对象在内的任意类型。

其他的细节问题

在 jQuery 1.6 之前,只有attr()函数可用,该函数不仅承担了attribute的设置和获取工作,还同时承担了property的设置和获取工作。例如:在 jQuery 1.6 之前,attr()也可以设置或获取tagNameclassNamenodeNamenodeType等 DOM 元素的 property。

直到 jQuery 1.6 新增prop()函数,并用来承担 property 的设置或获取工作之后,attr()才只用来负责attribute的设置和获取工作。

★★★★★
此外,对于表单元素的checkedselecteddisabled等属性,在 jQuery 1.6 之前,attr()获取这些属性的返回值为 Boolean 类型:如果被选中(或禁用)就返回true,否则返回false

★★★★★
但是从 1.6 开始,使用attr()获取这些属性的返回值为String类型,如果被选中(或禁用)就返回checkedselecteddisabled,否则(即元素节点没有该属性)返回undefined。并且,在某些版本中,这些属性值表示文档加载时的初始状态值,即使之后更改了这些元素的选中(或禁用)状态,对应的属性值也不会发生改变。因为 jQuery 认为:attributecheckedselecteddisabled就是表示该属性初始状态的值,propertycheckedselecteddisabled才表示该属性实时状态的值(值为 true 或 false)。

因此,在 jQuery 1.6 及以后版本中,请使用prop()函数来设置或获取checkedselecteddisabled等属性。对于其它能够用prop()实现的操作,也尽量使用prop()函数。

a 标签 href

href 属性和 onclick 属性触发事件 event 对象 this 不是同一个对象

href :触发事件的 this 是 window 对象

onclick :触发的事件 this 是控件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<html>
<head> </head>
<body>
href的event对象是window,因此这个this就是指的window
<br />
<a href="javascript:href_function(this,'href_function')">
href="javascript:href_function(this,'href_function')"
</a>
<br />
<br />
onclick的对象是当前控件a,因此可以获取控件a(链接)相关的信息
<br />
<a href="javascript:void(0)" onclick="_click(this,'_click')">
onclick="_click(this,'_click')"
</a>
</body>
</html>
<script>
var ss = '我是window对象的属性';
function href_function(obj, param) {
alert(param);
alert(obj.outerHTML); //undefined
alert(obj.ss); //我是window对象的属性
}

function _click(obj, param) {
alert(param);
alert(obj.outerHTML); //<a href="javascript:void(0)" onclick="_click(this,'_click')">onclick="_click(this,'_click')"</a>
alert(obj.ss); //undefined
}
</script>