js个人笔记

来源:互联网 发布:怎么看是淘宝客推广的 编辑:程序博客网 时间:2024/06/07 00:01


基础

1,逻辑运算符优先级 ’&&‘ > ‘||’。

2,===可避免引起混乱的隐式类型转换,建议使用。==只关心内容不关心数据类型,===都关注。但是NaN == NaN是false的,boolean的true和false是存储为1和0的,true==“true”是false的true==1是true的。基本类型下 ===只有当类型和数据都相等时为true ,引用类型下 ===只有当左右两侧指向同一内存地址时为true。

3,强制转换为Number(字符串/boolean)或者parseInt(),Number(小数点)会把小数去掉,Number(数字字母)解析为NaN,Number(空格)解析为0; parseint(小数点)解析不去掉小数,parsetInt(数字字母)会解析到第一个非数字字符为止。

4,boolean类型false: " ",Null,NaN,underfined,0,false;其余均为true。

5,隐式转换:Number:可以使用+ - * /进行转换,a = +a;   字符串:a = a + "";   boolean: a = !!a;

6,数据类型:简单数据类型:string number Boolean Null  undefined 复杂数据类型:object (其中特殊对象:array function)。简单数据类型(又称值类型)存放在栈中,复杂数据类型(又称引用类型)存放在堆中。例如:var b = new object(); 在堆的的内存中存放new object()对象,该内存地址为ox118,则栈中存放var b = ox118,使得b指向该对象。数组存放同理。js数组不同于其他语言,数组不定义长度无穷大,数据类型不限制。

7,函数:用来封装经常使用的代码块。用return返回值。

混淆点

1,typeof,instanceof

typeof:

返回值是一个字符串,该字符串说明运算数的类型。typeof 一般只能返回原始类型或者函数,如下几个结果:

number,boolean,string,function,object,undefined。我们可以使用 typeof 来获取一个变量是否存在,如 if(typeof a!="undefined"){alert("ok")},而不要去使用 if(a) 因为如果 a 不存在(未声明)则会出错,对于 Array,Null 等特殊对象使用 typeof 一律返回 object,这正是 typeof 的局限性。

instanceof: 判断一个变量是否是某对象的实例。eg:var a=new Array(); alert(a instanceof Array)

存在问题:

无法识别 Array, 即伪数组,因为数组其实也是对象。 解决方案

相关链接:http://www.cnblogs.com/mofish/p/3388427.html

var is_array = function (value) {
return Object.prototype.toString.apply(value) === '[object Array]';
}
Object.prototype.toString的行为:首先,取得对象的一个内部属性[[Class]],然后依据这个属性,返回一个类似于"[object Array]"的字符串作为结果(看过ECMA标准的应该都知道,[[]]用来表示语言内部用到的、外部不可直接访问的属性,称为“内部属性”)。利用这个方法,再配合call,我们可以取得任何对象的内部属性[[Class]],然后把类型检测转化为字符串比较,以达到我们的目的


无法识别 null 解决方案

if (myvalue && typeof myvalue === 'object') {
// myvalue 是一个对象或数组
} else {
return 'null';
}
无法识别 NaN 和数字

JavaScript 提供了一个 Number.isNaN 函数,可以辨别数组和 NaN

if(a !== a){ //a就是NaN}

typeof NaN === 'number' // true

NaN === NaN // false
NaN !== NaN // true
isNaN(NaN); // true
isNaN(0); // false
isNaN('opps'); // true
isNaN('0'); // false

PS:== 只有在两个运算数类型一致时才会做出正确的判断。如果两个运算数类型不一致那么将会强制转换值的类型。== 运算符在某些特例上违背了传递性(x == y and y == z 为true, 那么 x == z为 true),请不要使用==或者!=运算符,请使用 === 和 !==



2,call apply 是为了动态改变this而生~是在制定this和参数的前提下调用某函数/方法,

function Animal(name){    
    this.name =name;    
    this.showName = function(){    
        alert(this.name);    
    }    
}    
  
function Cat(name){    

    Animal.call(this , name); 

}    

以上函数等同于

function Cat(name){

this.name=name;

this.showName=function(){

alert(this.name);
}
 }
 


//通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。

使用情景:当一个object没有某个方法,而其他对象有,就可以用apply call bind进行调用该方法。call参数罗列,apply参数以数组或者类数组对象形式传递。当你的参数是明确知道数量时,用 call,而不确定的时候,用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来便利所有的参数。


3,prototype,_proto_

图解:_proto_属性每个对象都有的属性,prototype是函数才有的属性。prototype是显示原型,_proto_是隐性原型。

函数prototype包含_proto_和constructor属性。子对象prototype的_proto_属性指向其父对象的prototype属性;constructor属性指向其自身函数。

对象的_proto_属性指向其父对象的prototype属性。

函数作为对象也有_proto_属性,指向其构造函数Function的prototype属性;



ps:[[prototype]]同_proto_是对象都有的内置属性,ES5开始可通过Object.getPrototypeOf()方法获取。f._proto_=== Object.getPrototypeOf(f);

4,对象引用

var a = new Object();

a.value = 1;

var b = a;

b.value = 2;

console.log(a.value); //2

var b={value:3}

console.log(a.value); //2

b是对a的引用 指向同一个内存地址。b的修改会影响a。当b重新赋值时重新指向新地址 a不会受影响。

浅拷贝和深拷贝的区别就在于,浅拷贝是AB指向同一内存地址 B改变会影响A。而深拷贝是基本类型的拷贝,深入内层属性,不会相互影响。

深拷贝方式之一:可借助var b = JSON.parse(JSON.stringify(a));


{a:1,b:2,c:3}不会发生改变。


0 0
原创粉丝点击