Javascript知识点

下面记录一些重要的js知识点,防止遗忘

(1)js中的函数声明提升,可以让函数调用先于函数声明语句,因为在代码执行之前会先读取函数声明

(2)childNodes属性要返回文本节点(3)以及元素节点(1),最好不使用,代替为children,firstNode和lastNode也有可能是文本节点

    文本节点不一定有看得见的文本,换行符也算一个文本节点,如下图,div有3个子节点,头尾2个都是textNode

    只有div和p紧紧相连才没有文本节点

class="d1">

s


(3)同上,要获取一个元素节点的前一个或者后一个节点的话,使用previousElementSilbling/nextElementSibling  来获取,如果用previousSibling则会获取到文本节点

(4)创建一个新元素方法:

     var newElement = document.createElement(标签名)

     document.body.appendChild(newElement)

(5)DOM事件:stopPropagation(),比较有用,用于当大div里有小div,且二者都有onclick,如果不在小div添加event.stopPropagation()则点击小div会先后触发2个div的onclick

(6)HTML5 canvas 画图像的要点:必须等待图像加载完成后再调用drawImage,否则图片不显示,

var image = document.images[0];
window.onload = function(){
    drawingContext.drawImage(image,0,0,300,400);
}


(7)html5中拖动滑块获取其值的方法(oninput)

range:type="range" id="range1" min="1" max="10" οninput="getValue()"/>
var r = document.getElementById("range1");
var p = document.getElementById('p');
function getValue(){
    p.innerText = ((r.value / r.max)*100).toString()+"%";
}


(8)js将一个数组赋值给另一个数组: 不能直接var arrayB = arrayA,这只是多了个引用,其实2者都对应同一个数组,应该如下做:

var a = [1,2,3];
var b = a.slice(0);
a.push(4);
console.log(b.join());
console.log(a.join());

(9)js中提升的概念非常重要:所有的声明如函数和变量的声明都会被提升到作用域顶端,而函数表达式不会被提升,因为是赋值操作,另外函数优先于变量被提升

例子: console.log(b),会导致reference error 而console.log(b);var b = 2  输出 undefined

尽量避免在快内部声明函数,这会导致函数声明被提升到块作用域的顶部

var a =2 这一句话被编译器理解为var a; a = 2;前者只是声明,后者是赋值


(10)call apply方法解释,首先这2个方法都是Function原型里的,用法:functionName.call(thisObj,arg),  call 和apply会将functionName这个函数的调用放到thisObj的上下文

里,改变this指向,2者区别是参数不同,apply参数是数组

//call apply
var color = 'green';
function lqy(){
   this.color = 'red';
}
function sbw(){
    this.color = 'blue';
}
var o  = {color:"blue"};

function showColor(){
    alert(this.color);
}
var lqy = new lqy()//实例化该函数
showColor.apply(lqy);//red 
showColor.call(sbw());//blue
showColor.call(this);//green
showColor.call();//green

(11)event: clientX 事件属性返回当事件被触发时鼠标指针向对于浏览器页面(或客户区)的水平坐标。可以用来计算拖放

(12)函数节流,比较重要,window.onresize函数会导致连续不断的执行其中的代码,性能损耗严重,所以需要设定最小间隔时间来执行代码

这样当等待500ms后才会执行该函数,如果在小于500ms间隔内改变窗口大小都不会触发该函数,因为该函数未执行,所以直接clear掉然后再

添加新的settimeout,继续等待500ms

function throttle(method,context){
            clearTimeout(method.tId);
            method.tId=setTimeout(function(){
                method.call(context);
            },500);
        }


(13)区分ie,注意ie 11要特殊处理

 
  
var nav = navigator.userAgent;
//区分是ie还是不是ie,ie11不支持
if(!+[1,]){
    alert("ie < 11");
}
else if(nav.indexOf('Trident') > -1 && nav.indexOf("rv:11.0") > -1){
    alert('ie == 11');
}
else{
    alert("not ie");
}


(14) 快速将日期转为数值

var t = +new Date(),也可以用valueOf


(15)如果要让链接点击不做任何事,可以如下做

一个井号不行, 因为会默认到页面顶部

也可以


(16)各种宽高一张图搞定

Javascript知识点_第1张图片


(17)脚本永不出错的方法: window.onerror = function(e){return true;}


(18)使用!!variable 可以把变量转化为bool值


(19)undefined null NaN的区别:

       首先,null 和 undefined是基本的6种主要类型之一,NaN(Not a Number)是一种特殊的数字,typeof(NaN)为Number

undefined 表示声明了变量未赋值或者引用对象不存在的属性时会出现undefined提示

null表示空,但不为0,可以显式给变量赋值null清空变量,null==undefined但不全等

而NaN表示减,乘,除 运算结果不为数字的后果,比如5-"a"表示为NaN,其中NaN不等于自己,因为是一个范围


(20)delete操作符,很蛋疼,记住以下几点

      1,最常用来删除对象中的属性,如 var a = {b:1} ; delete a.b,返回true

      2,用var声明的变量和函数无法删除

      3,全局变量可以删除,比如 a=2,然后delete a是可以的


(21)想让一个对象不可变,可以调用Object.defineProperty方法或者Object.freeze或者Object.seal


(22)检测一个属性是否存在于对象中,不能用object.property == undefined来 判断,因为有可能其值就是undefined

方法有2种,第一是用in,propertyName in Object ,注意propertyName是字符串,这个会检查当前对象以及其原型链是否有属性

第二种是hasOwnProperty,这个方法只会检查当前对象是否有属性


(23) in操作符可以检查属性名是否存在对象中,但数组要小心,数组的属性名是下标0,1,2....不是其value,而对象属性名则是key

另外遍历对象的顺序是不确定的,数组是确定的


(24)全等操作符 和 相等操作符

 == 比较时要转换为数值,例如"55" == 55 //TRUE,bool值转变为0或者1,字符串转为数字

=== 比较时不转换 上面为false


(25)var s = String('str') 这个s就是'str' ,值类型    而 var s = new String('str') 这个s是字符串对象,是引用类型


(26)js中字符串和数字相加都转化为字符串加,比如5+'2' = 52,结果是字符串注意了,而相减则变为数字相减,结果是数字


(27)arguments解释:Javascript中函数中的参数是以数组的形式保存的,所以在JavaScript中调用函数给函数传递的参数时,不会受到我们定义函数时设置的参数个数的限制。也就是说如果我们给一个函数定义了2个参数,我们传递的时候可以不传,可以传一个,也可以传两个,传三个...都可以,不会受函数参数个数的影响。arguments类似一个数组(但是不是真正的Array对象),同样可以像数组一样用方括号来访问它的每一个值,并用arguments.length来判断参数的个数。


(28)原型:在JavaScript中,我们创建一个函数A(就是声明一个函数), 那么浏览器就会在内存中创建一个对象B,而且每个函数都默认会有一个属性 prototype 指向了这个对象( 即:prototype的属性的值是这个对象 )。这个对象B就是函数A的原型对象,简称函数的原型。这个原型对象B 默认会有一个属性 constructor 指向了这个函数A ( 意思就是说:constructor属性的值是函数A )。

继承是通过原型链来继承

B.call(this)是类继承


(29)js中最大整数为Math.pow(2,53)-1 具体为9007199254740991,16位数字

(30)js for循环闭包问题最简单的解释:

var body = document.body,
    button,
    i;
for(var i=0;i<5;i++){
    button = document.createElement("button");
    button.innerHTML = "button"+i;
    (function(i){
        button.addEventListener("click",function(e){
            alert(i)
        },false)
    })(i)
    body.appendChild(button)
}
上面不加闭包前 并不是传参,只是在函数内部引用了i,且都是同一个i,在执行时i已经变为5了,所以5个button都是5

加了闭包就变成传递函数参数了,传递的是值,复制的,不是引用,所以每个i都不同,注意这里立即执行了该匿名函数,否则函数里面的语句不会生效


(31)删除一个元素必须通过父元素的removeChild,所以node.parentNode.removeChild(node)

(32)getElementsByClassName("c1 c2 c3")参数可以是多个类组合,顺序不重要,而且可以匹配部分类名,就算元素带有更多类名也没关系

(33)ES6: 如果对复合变量声明为const,则要尤其小心,

如const obj = {} ; obj.a=5 可以改变对象属性,但是不能改变对象地址,再使用obj={}则报错,因为const仅仅让对象地址不可变,内容则是可变的

(34)ES6中,在最外层声明let a =1 则window.a = undefined 规定let声明的变量不属于全局对象属性,而var则是


(35)document.write()会重绘当前页面,而innerHTML不会,控制范围更精确


(36)js中提取子字符串最好用substring(start,end),返回新的字符串,start代表字符串开始位置,end代表结束位置加1,不指定end则直到末尾


(37)以下2个链接,第一个触发了click事件后不会触发点击事件,return false起作用了


(38)  var b;

typeof b === 'undefined'   //true 因为typeof返回字符串

b === undefined //true 这里不是字符串注意了


(39)统计代码用时

var times = 'loop';
console.time(times);
for(var i=0;i<100000000;i++){

}
console.timeEnd(times);


(40)数组中的索引也可以是字符串,但是这样不会增加数组长度,如果字符串可以被转为10进制,则例外 ,如

var a = [];

a['100'] = 1

console.log(a.length) // 101


(41)concat方法,将2者拼接在一起,支持数组和字符串,返回一个新的对象而不是在原来基础上修改,参数可以是多个数组或字符串

var s = s1.concat(s2)


(42)splice方法,arr.splice(pos,count,item) 该方法在pos位置开始删除元素,删除count个,用item来替代,item可以没有,直接修改原数组,不同于slice


(43)反转字符串,字符串是不可变的,也没有reverse方法,所以要如下处理

s.split('').reverse().join('')


(44)想要禁止表单元素的输入可以有2种方法,第一个是 第二个是利用js,获得焦点的同时失去焦点,好处是无法复制表单内容

     

var input = document.getElementById("input");
input.onfocus = function(){
    input.blur();
}

(45)防止用户复制粘贴,其实是可以进行右键复制操作的,但是无法获取内容

var p = document.getElementsByTagName('p')[0];
p.onpaste = function(){
    return false;
}
p.oncopy = function(){
    return false;
}

(46)动态定义正则表达式,注意参数没有斜线了

var name = 'sbw';
var reg = new RegExp("^("+name+")|("+name+")$","g");
alert(reg.test('eresbwer'))

(47)js中假值有如下几个,其余都是真值,可以用Boolean()来判断

undefined

null

''

NaN

0

false

(48)js中的一元运算符+,用来将字符串显示转化为数字

var c = '12'

typeof +c  //number


(49)获取一个node的css样式一定要注意:

1,如果是内联样式,也就是

这种,才可以用node.style.width读,否则获取到的是空对象

例外:如果没有内联样式,可以用node.style.width=xxx来写,这样就有内联样式了,后面就可以读取了

2,不是内联样式,可以用window.getComputedStyle(node,null).width获取宽度等样式,只读,写的话setAttribute('style',' .......'),

这个方法是获取最终计算的style结果


(46)settimeout函数传递参数写法:setTimeout(function(){yourFunc(arg1,arg2)},1000),用一层函数包起来

(47)判断bo参数为true的个数(参数不一定是true,比如为''1''也是true),利用隐式转换,true为1,false为0

//只有一个true,利用bool隐式转换
function onlyOneTrue(){
    var sum=0;
    for(var i=0;ilength;i++){
        sum+=Number(!!arguments[i]);
    }
    return sum===1;
}


(48)js 中,|| 和 &&返回的是操作数,如4||5返回4, 0&&100返回0,  0||6返回6,而不是true和false

(49)重要的地方:判断一个值是否为true或者false最好这样用

if(a) 或者if(!!a) 

不要这样用

if(a == true)或者if(a===true),因为5==true为false,这里会发生转换,true被转换为1,然后执行比较1==5,当然为false


(50) null==undefined 但是null!==undefined因为类型不同


(51)判断数值类型可以用  typeof(v) == 'number'来判断


(52)动态改变textarea高度,随着文字增多变高,注意要加px否则不起作用

    

(53)如果给html元素添加id属性,那么这个id会成为全局变量,这一点要小心使用

alert(d) //htmlObject


(54)一个html中有多个则后面的标签内的js代码可以调用前面标签中的方法和变量,这些标签共享一个global对象(window),但是函数声明提升却不起作用


(55)get,set方法的坑,不应该在get,set方法内使用改变属性值的操作语句,否则无限递归调用

get方法触发条件:当要获取age的值的时候

set方法触发条件:设置age值的时候

var obj = {};
Object.defineProperty(obj,'age',{
    get:function(){
        //此处会出现栈溢出,原因是在get方法内继续调用get方法
     //obj.age --;
        return 1;
    },
    set:function(value){
        //此处会出现栈溢出,原因是在set方法内继续调用set方法
     //age = value;
    }
})

(56)判断字符串中是否存在另一个字符串,可用indexOf,search和正则等方法

(57)一个坑:js中只有一个删除节点的方法removeChild(),若想要删除所有子节点

如下写法不行,因为每次删除后索引要改变,可从后往前删除或者用while删除

for(var i=0,len=parent.children.length;i;i++){
    citySelect.removeChild(citySelect.children[i]);
}

(58)比较价格大小不能直接比较字符串大小,必须parseInt,因为'300' > '2000',首先按照首字符比较大小


(59)获取图片的宽高直接用var height = img.height; var width = img.width即可


(60)js中如果一个函数定义了一个bool参数,但是不传参,则参数默认为false,因为默认是undefined,等于false


(61)Array.splice(arg1,arg2),其中arg1是要删除的位置,arg2是要删除的个数,有返回值,是包含被删除元素的数组,本来以为直接就是返回原数组,坑啊!


(62)js判断数组相等不能直接用==或者===,结果为false,因为数组是对象,而2个不同对象肯定不等,也不能用toString方法,

因为['1',2]  会和 [1,2]相等,也就是说无法辨别字符串和数字,应该用最原始的方法,比较每个值是否相同,用===比较


(63)js中toFixed方法返回的是字符串,不是小数(Number)记住了


(64)ES6中Set比较相等是用===来判断,所以2个对象肯定不同,如下,s的size为2,而不是1,更容易出错的是s.has([])为false,因为这3个[]根本不是同一个对象

var s = new Set();
s.add([])
s.add([])
alert(s.size)


(65)js中数组遍历方法有几种,假设数组为array

        1,最原始的方法

for(var i=0;i

console.log(array[i])

}


2,数组内置的forEach,但不能跳出循环

array.forEach(function(v){

console.log(v);

})


3,es6新增的for...of

for(let v of array){

console.log(v)

}


4,for....in,这个方法有缺点,一般用来遍历对象而不是数组


(66)一个获取指定元素style的通用方法,兼容各种浏览器

function getStyle(eleNode){
    var style = null;
    if(window.getComputedStyle){
        style = window.getComputedStyle(eleNode,null);
    }
    else{ 
        style = eleNode.currentStyle; //ie独有的方法
    }
    return style;
}


你可能感兴趣的:(Javascript知识点)