js使用记录
“/”表示服务器根目录,“../”表示当前目录的上一级目录,“./”表示当前目录
对于 return、break、continue 等语句,如果后面紧跟换行,解析器会自动在后面填充分号(;)
function foo2() //返回undefined { return { bar: "hello" }; }
‘’加数字转为字符串,'+/-'加‘数字’转为数字。
js中对象的底层是一个hash数组,为一个对象设置属性时,js会隐式的将属性名字符串化,所以obj["属性名"]===obj.属性名。obj["prop"]可以动态拼接字符串生成属性名,更灵活。
var a={},b={key:'b'},c={key:'c'}; a[b]=123; //a[‘[object Object]’] a[c]=456; //a[‘[object Object]’] console.log(a[b]);//456
_.each(colloction,function(value,key){…}),返回原素组,对集合中的每个元素运行一遍function。
_.map(colloction,function(value,key){…}),返回新数组,由原集合中的每个元素调用函数后的return结果组成。
把任何标签元素的contenteditable属性(不属于css样式)设置成true,在页面上点击即可直接编辑该元素的内容。
在控制台运行下面代码也可以使页面处于可编辑状态:document.body.contentEditable='true';或document.designMode='on';
mouseover:若移动到子元素内,会触发此事件。从子元素移动到父元素内,会再一次触发。子元素支持冒泡属性,对应mouseout。
mouseenter:若移动到子元素内,不会触发此事件,除非移动出父元素。不支持冒泡属性,对应mouseleave。
访问undefined的属性会报错,可以设前置条件避免访问undefined的属性值:
利用短路逻辑if(obj&&obj.prop),若obj为undefined,则为假值;或用三目运算增加前置条件。
引号嵌套:引号里面不能有相同的引号,单双引号要错开使用。连续两个最近的单引号/双引号为一对;若多级嵌套,使用转义字符转义。
原生js访问class要用className。
splice() 方法 用于插入、删除或替换原数组的元素。
slice() 方法 可提取数组或字符串的某个部分,并返回被提取的部分,原数组/字符串不变。比substring方法更灵活,Substring的两个参数中小的数为起始下标,和定义前后没有关系。
splice 的参数 :splice (start, deleteCount, [item1[, item2[, . . . [,itemN]]]])
数组从 start下标开始,删除deleteCount 个元素,并且可以在这个位置开始添加 n个元素。当start ,deleteCount 均为0 的时候,也就是在数组的最前面插入新的元素。
当 参数有 start和deleteCount时,是从start 下标开始删除deleteCount 个数组的元素;当参数只有start参数时,就是删除 从start下标起至最后的元素。
当参数为负的时,则从数组元素的尾部开始算起的位置 (-1 指的是 数组中倒数第一个元素, -2 指的是,数组中倒数第二个元素。)
slice 参数 : slice(start,end);
slice 方法提取 从 start下标起 以end下标 为结尾的 一段元素(但不包括end下标的元素),然后返回新的数组,对原数组没有任何是影响。
当参数为负时,则该参数是从数组的末尾 索引开始算起,(-1 指的是 数组中倒数第一个元素, -2 指的是,数组中倒数第二个元素。)
当参数为一个参数,提取是以 start下标起 至末尾的 部分元素。
当start 为0 时, 等于说是克隆一个新的数组,克隆后两个数组进行各自的操作,互不影响。
var clone = arr.slice(0);
借用concat()函数进行数组的复制:var clone= arr.concat();返回的结果是一个新的数组。
delete 删除对象的属性或删除数组元素。注意从对象的原型链上继承而来的属性在对象上删除不掉;delete数组元素时数组长度不变,原来的位置为undefined。
操作成功返回true,否则返回false。
循环时如果要删除数组中的元素,使用splice(i,0),然后i--,不然会少遍历一个元素。
concat/push(ele1,ele2…)可同时操作多个元素
快速复制对象的hack,先用JSON.stringfy转换生成字符串形式,再用JSON.parse转换为对象。
jQuery为了提供跨浏览器的一致性,它始终会在冒泡阶段注册事件处理程序,不支持事件捕获。因此最具体的元素会首先获得响应事件的机会。
1.阻止事件冒泡,但不阻止默认行为,用stopPropagation。
2.阻止默认行为,但不阻止事件冒泡,用preventDefault 。
3.同时阻止事件冒泡和默认行为,并终止当前方法,return false 。而return只是终止当前函数的执行。
点击a链接,会先执行相应的click事件处理函数,再跳转到相应的链接上。因此可以判断不同的结果跳转到不同链接(在handler中修改href属性,事件处理完就会跳转到新链接地址)或return false 直接终止跳转。最好是不要通过a链接跳转,而是通过js直接调用window API打开新窗口。
event.currentTarget = 回调函数内的this = 注册监听函数的元素(对象)
eg:你点击的元素不一定就注册了回调函数,也许是它的父元素注册了事件处理函数。
event.target = 事件作用的元素(对象)
eg: 如果是一个点击事件的话,那么你点击了谁,谁就是这个点击事件的作用对象。
触发DOM事件,会产生一个event事件对象,浏览器会将这个event对象隐式传入事件处理程序中,作为arguments对象的第一个元素。回调函数内即使不用形参e接收event对象也可以直接使用event,但最好传入形参。
递归:要有终止条件,往闭合的方向执行。
如果点击事件触发不了,可检查事件处理函数有没有绑定上;还有就是看有没有别的高z-index隐形元素遮住了元素,导致点击无效。
document.write在页面流输入过程中执行。一旦页面加载完毕,再次调用 document.write(),会隐式地调用 document.open() 来擦除当前文档并开始一个新的文档。
history是在当前页面后面压入记录。点击跳转而不是前后操作时,如果当前页面后面有记录,则会丢失。
前台请求资源时在后面追加参数,如时间戳(或其他版本性字符),可以更新缓存。
算2个时间之间的月份差,把年份统一调整为月数,再相减。Date对象的setMonth()可以接受任何范围的数字,Date
对象内部会自动计算并转换为对应的日期。月份是从0开始的。
new Date().setMonth(月份差)//负数Date对象会自动调整
offsetParent返回第一个非static布局的父级元素,即postion的值是 absolute,relative或fixed中之一。如果父级元素都是static布局,最后返回的是Body。
offsetLeft和offsetTop分别返回相对offsetParent的位置,也就是返回相对第一个非static布局的父级元素的位置。
background-origin:content-box/border-box/padding-box;只对背景图有效。
background-clip: content-box/border-box/padding-box;对背景色也有效。
clip:reac(v1,v2,v3,v4);只裁剪绝对定位的元素。
css选择器中,:hover后面可以再接子元素或后面的兄弟元素
背景图最好用标签占位,不要直接使用padding。方便小图合并,换个坐标就行。
如果某个按钮可能会被暂时禁用,最好用button通过disabled属性来实现;或加个透明遮罩层。
:active 伪类向激活(在鼠标点击与释放之间发生的事件)的元素添加特殊的样式。
一个字节可以有一对(2位)的十六进制表示1 byte= 0xFF
typeof一元运算符,返回值一个字符串用以说明运算数的类型。t只能返回如下几个结果:
number,boolean,string,function,object,undefined。一般用于判断一个变量是否存在:
if(typeof a != "undefined") …
instanceof 用于判断一个变量是否某个对象的实例
动态循环生成表格,设置rowspan时有效,但每行都会累计往下合并,遍历一行多一个td。因为html中首个合并行后的每个row都要会少一个td才能对齐。所以可以把每一个类别的首行为定位行,只有首个td有内容(高端SUV),后面的td为占位td,display为none。
每个类别的首行之后的tr比首行要少一个td,遍历输入内容。首行height要设为0。
【height为0的妙用:内容依然显示,但框模型不占空间。】
对象说明符(object specifiers)/参数json格式化
function test(a, n, c}){
console.log(c,n,a);
}
test(11, 'chen','shanghai'})
//参数必须按顺序传入,形参才能被正确赋值,当参数过多时不方便。
function test({age:a,name:n,city:c}){
//形参仍然是a,n和c,形参通过属性名(对象说明符)根据实参被正确赋值。
console.log(c,n,a);
}
test({name:'chen',age:11, city:'shanghai'})//有对象说明符,顺序不重要了
对象字面量中属性名不能用变量,只能是固定的名称,变量标识符key会被当做对象的属性名[key]而不是变量。
可以分多步用[]重新定义:
var obj={};
obj[key]=BQ[key];
arr.push(obj);
ES6中才支持对象字面量的属性名中用变量:
var obj = {
[key] : value
}
$.proxy和bind:接受一个函数,返回一个永久绑定了指定的context的函数。bind是原生方法,性能更好。
setTimeout($.proxy(function(){
console.log(this);
}, this), 5000);
setTimeout((function(){
console.log(this);
}).bind(this), 5000);
伪协议说明符javascript:
这个协议类型声明了任意的URL的主体可以是javascript代码,它由javascript的解释器运行。如果javascript:URL中的javascript代码含有多个语句,必须使用分号将这些语句分隔开。js代码把最后一条javascript语句的返回值且该返回值为字符串的值作为新文档的内容显示出来。(浏览器之间不一样,有些不会覆盖原来的文档)
若用javascript:URL执行某些不改变当前显示的文档的javascript代码,必须确保URL中的最后一条语句没有返回字符串值或添加void 0。
javascript URL可以含有只执行动作,但不返回值的javascript语句。由于没有作为新文档来显示的值,因此它并不改变当前显示的文档。
switch(exp){
default:{…};
break;
case value:{…};
break;
}
switch先从case开始依次匹配寻找入口:如果没有匹配的case,则将default语句当做执行入口,而不管default语句写在头还是尾(若default无break,则一直往下执行直到break或switch语句结束)。如果有匹配的,则从入口处开始从上往下执行,直到碰到break跳出switch语句或执行完整个switch语句(此时default不是必须要执行的语句,如果在前面,不会再跳回去执行)。
函数声明时可以没有参数,在内部通过arguments指代具体参数,调用时再直接传参。
this指函数调用的对象:obj.foo();//this值obj
foo()是一个整体,表函数的调用,再找之前的"."。
注意
1.回调函数(setTime等)、函数赋值和调用分开执行的情况:
var baz=obj.foo;
baz();//this值window;两句js语句
2.new Foo()为构造_调用,会改变this的值指向新对象,构造函数里的语句也会依次执行。会产生执行环境,有可能会有闭包形成。《取号机》
函数参数也是局部变量,在内部会被修改,适用变量提升规则;同时会修改arguments对象中对应的值【无变量名,只有值】。
hasOwnProperty 和 in 区别?
hasOwnProperyt只搜索实例中的属性;只支持标识符
in还包括整个原型链;只支持字符串形式,不支持标识符
parseInt(var,10);只有当var不为0X或0开头时,才默认转为10进制,所以radix不要省。
在检查变量是否存在时,不要只用var名,因为可能变量存在但的值为undefined:
if(typeof somevar !== 'undefined')
function add({num1:a1,num2:a2}){
return a1+a2;//形参用对象说明符形式,属性值直接在函数体中使用;属性名在传参时再用
}
var sum=add({num2:5,num1:8}); //参数过多时,不用按指定顺序传参
_.template(data); //模板函数调用也是采用这种形式???。
arr.toString();和fun.toSting();返回其原始字符串值
obj.toString()返回[object Object],没有什么用
if(s.indexOf("XXX") !== -1) …//不要和0比较,有可能第0个字符就匹配到。
如何记忆初始化状态??
默认情况下,Date对象返回的都是当前时区的时间。Date.UTC
方法可以返回UTC时间(世界标准时间)。该方法接受年、月、日等变量作为参数,返回当前距离1970年1月1日 00:00:00 UTC的毫秒数。
因为js无需编译,所以在chrome里修改js文件保存后可以直接运行测试,不用在源文件中改。
算日历中第n周的所属月份:
先算当年1月4号(所在周为当年第一周)的星期几(周日为0),取负数和4相加,再和周数折算为天数相加,调整后的当年第n周已经过了的天数。
例外:53周直接在12月。
参数对象标识符形式
如果形参为多个,调用函数时,要根据形参的顺序依次从实参中取值、赋值。如果参数过多,顺序容易出错。此时可以用参数对象标识符,不用按照顺序传入参数。
形参对象的属性名为js标识符,一旦定义就不能改变。所以属性值为才是真正的参数变量,在函数内部直接使用。调用时,形参变量会根据属性名从实参中取值初始化。
var para={arg1:15,arg2:"lily",arg3:"shagnhai"}; function test({arg1:name,arg2:age,arg3:addr}){ console.log(name+age); //形参变量为name,age和addr,标识符为arg1、arg2和arg3 } test(para); var para={age:15,name:"lily",addr:"shagnhai"}; //定义函数时参数采用json对象格式方便,也不用管顺序 function test2(para){ console.log(para.name+para.age); //形参变量为para } test2(para);
ie 7/8不支持trim(),改用String.replace(/^\s*/, '' ).replace(/\s*$/, '' )
三目运算优先级只比赋值运算符高,低于=-*/和比较运算符:'</div>'+condition?value1:value2;结果都为value1,因为'</div>condition'永远为真。
真确的写法'</div>'+(condition?value1:value2)。
三目运算符可以嵌套:5<3?0:6>4?2:8;执行顺序从左往右
onfocus获得焦点,光标在元素内一闪一闪;onblur失去焦点,光标不在元素内。两者为相反的事件。
如何区分点击事件是代码触发还是鼠标触发?
//鼠标点击,在event对象中会有点击时x/y坐标值;代码触发的没有。 $("#btn").click(function(e){ if(e.hasOwnProperty('originalEvent')) //jq将原生事件对象封装到jq的事件对象中 // a real click. else //a fake click. });
HTML元素的onload事件,加载后执行回调:
<script src="/js/common.js" type="text/javascript" onload="alert('loaded')"></script>