慕课网 深入浅出javascript 笔记
javascript 数据类型
- 5种简单数据类型:Number、String、Boolean、Undefined、Null
- 1种复杂数据类型:Object
- = 表示赋值;
- == 表示比较,但是会做隐式类型转换。比如,"1 == true", 此时,1会从一个Number数 据类型转换到Boolean数据类型,进而再做比较;
- === 表示比较,数据类型不同则不相等,因而相对于“==”也更严格一些。3===“3”;会返回false;因为不会转换他们的数据类型数字和字符串当然就不相等了
- 对象和对象比较,是比较的引用,两个对象都是new出来的(新创建出来的),所以是不同的对象,不同的对象的引用是不同的,所以输出是false
基本包装类型
- 基本类型是没有属性的,但是在对string/number/boolean进行访问和设置属性这样的操作时,js会将其临时转换为对应的包装对象类型String/Number/Boolean,这样就可以访问或设置属性
- var str = "string"; 2. str.t = 5; //5 3. alert(str.t) //undefined, var str = "string"; 这个str是基本类型string, str.t = 5 基本类型没有属性和方法, 因为此时js引擎中会自动创建一个对象,即 var str = new String('string');然后再调用这个对象的方法和属性,str (这里我叫做0号)这个对象,仅仅在代码执行的一瞬间被创建,然后马上被销毁。alert(str.t) //undefined 此时的str.t 又会创建一个新的str对象(这个就是1号),和之前创建的str对象(0号)是不同的对象,而这个新的str对象(1号)刚创建,没有t属性,所以会弹出 undefined
类型检测
- constructor指向构造器或构造函数,构造函数的prototype指向原型对象,构造函数实例的prototype也指向原型对象,实例与构造函数没有直接关系
- typeof 主要应用在基本类型的检测,instanceof 主要应用在自定义的对象或者原生对象,instanceof是基于原型链的一个操作符,用于判断对象类型;返回的结果是true或false;
表达式
原始表达式
- 常量,直接量 3,14 "test"
- 关键字 null this
- 变量 i,j,k
复合表达式
10(原始表达式) * (运算符)20
数组,对象初始化表达式
- [1,2,3]
- [1, ,,4]
- {x:1,y:2}
函数表达式
- var start()=function(){};
- (function(){alert("hello word");}//直接调用
属性访问表达式
- var o={x:1};
- o.x
- o["x"]
调用表达式
- fun();
对象创建表达式
- new Func(1,2);
- new Object;
运算符
- 修改属性默认特性,使用object.defineProerty()方法,方法有三个参数:属性所在对象,属性的名字,和一个描述符对象,描述符对象包括:configurable,enumerable,writable,value
- 使用hasOwnProperty()方法检测一个属性存在于对象实例中,才会返回true
var语句 block语句
- b为隐式的定义成全局变量
函数声明的提升
switch语句
对象:对象中包含一系列的属性,这些属性是无序的,每个属性都有一个字符串key和对应的value;
- var obj ={ x:1,y:2}; obj.x;//1 obj.y;//2
- 对象的结构: 对象中的每个属性都有很多属性标签:是否可写的writable,是否可删除的enumerable,是否可枚举的configurable,value,get/set
- 每一个对象都有一个原型[prototype] 每一个对象有一个[class],表示属于哪一个种类 每一个对象有一个[extensible],表示对象是否允许继续增加属性
- 所有函数x都有prototype属性,且这个属性是一个对象。 且x.prototype也有原型即Object.prototype。 注意这个原型里有一些默认的方法。
- 查找属性是按原型链 自下向上 查找。 所以如果下 和 上 有相同的属性名,那么肯定是下的起作用。 删除属性:delete 对象名.属性名
三种构造对象的方法如下:
- 对象字面量创建 var obj={z:78,y:"asd",o:{oo:"ooo"}}; obj.x="123";
- new原型链(构造器)function wc(){}; var ko=new wc(); ko.t=123;
- Object.create()方法var haha=Object.create({x:12,y:"nini"});
属性操作:
- 用for-in遍历时,原型链上的属性也会被遍历到,而且是无序遍历。
- 属性删除用delete, 可删除实例属性,从而访问原型属性,prototype属性不可被删除;var定义的变量也不可用delete删除,函数也不可以被delete掉
- 访问不存在属性,进行原型链查找,末端找不到,会undefined。
- delete 删除属性,重复删除同一个属性,任然返回true。所以delete并不代表操作成功或者失败了,而是说还有没有这个属性值。prototype不能被删除。
- a!=undefined。就是不等于null和undefined
JavaScript的闭包
- 闭包简单的说就是一个函数能访问外部函数的变量,这就是闭包,比如说:
function a(x){
var tem=3;
function b(y){
console.log(x+y+(++tem));
}
}
a函数中的b函数就是闭包了,b函数可以使用a函数的局部变量,参数,最典型的闭包应该是下面这样,将定义在函数中的函数作为返回值
function a(x){
var tem=3;
function b(y){
console.log(x+y+(++tem));
}
return b;
}
闭包的另一种作用是隔离作用域
for(var i=0;i<2;i++){
setTimeout(function(){
console.log(i);
},0);
}
上面这段代码的执行结果是2,2而不是0,1,因为等for循环出来后,执行setTimeout中的函数时,i的值已经变成了2,这就是没有隔离作用域所造成的
for(var i=0;i<2;i++){
(function(i){
setTimeout(function(){
console.log(i);
},0)
})(i);
}
这样就会输出0,1,我们的立即执行函数创建了一个作用域,隔离了外界的作用域,闭包的缺点是,因为内部闭包函数可以访问外部函数的变量,所以外部函数的变量不能被释放,如果闭包嵌套过多,会导致内存占用大,要合理使用闭包。