js基础笔记
一、js中含有6种数据类型:
原始类型(即基本类型):number、boolean、null、undefined、string 和 对象类型object(包含function、array、date等);
二、==和===的区别:
==会尝试进行数据类型转换,再进行比较:
null==undefined 相等;
number==string 时会转成number 如 1=='1.0' //true
boolean==?(无论?是什么)时会转成number 如 1==true //true
object==number|string(number或者string ) 时会尝试转成基本类型 如new string('hi')=='hi' //true 其他为false
===要求等号两边的数据类型必须相同,唯一例外的是NaN,new Object不相等,NaN≠NaN,NaN和任何数据都不相等;
三、包装对象:
var str='string';//基本对象string
var strObj=new String('string');//包装对象 对象类型 可以有属性、方法;
var str='string';
alert(str.length) //6
str.t=10;
alert(str.t) //undefined
当把基本类型尝试以对象的方式进行访问时,js会将基本类型转化为临时对象,当完成访问后,临时对象会被销毁,所以str.t为undefined;
四、类型检测:
1、typeof :判断基本类型和函数检测,遇到null返回Object失效;
typeof 100 //number
typeof true //boolean
typeof function //function
typeof(undefined) //undefined
typeof new Object() //Object
typeof [1,2] //Object
typeof NaN //number
typeof null //Object
2、instanceof:判断对象类型(基于原型链),适合自定义对象和原生对象;
Obj instanceof Object :判断左侧对象的原型链上是否有右边这个构造函数的prototype;
[1,2]instanceof Array===true
new Object() instanceof Array===false
注意:不同的window或者iframe之间的对象类型检测不能用instanceof,否则返回值全为false;
3、Object.prototype.toString:判断对象类型
Object.prototype.toString.apply([]);==='[object Array]'
Object.prototype.toString.apply(function(){});==='[object Function]'
Object.prototype.toString.apply(null);==='[object Null]'
注意:在ie6、7、8中Object.prototype.toString.apply(null);==='[Object Object]'
Object.prototype.toString.apply(undefined);==='[object Undefined]'
4、constructor
5、duck type
五、运算符:
1、条件运算符:
c?a:b;
var val=true?1:2 //如果val=true成立,则val=1,否则val=2;
2、逗号运算符:
a,b;
var val=(1,2,3);//从左到右开始计算,最终以最右边的值为主,val=3;
3、delete运算符:删除对象的属性;
var obj={x:1};
obj.x;
delete obj.x;//删除obj的x属性;
obj.x;//undefined
注意:configurable:false时,delete obj.x失效;configurable:true时,delete obj.x才有效;
var obj={};
Object.defineProperty(obj,'x',{
configurable:false,
value:1
})
delete obj.x;//删除obj的x属性失效,返回false;
obj.x;//1
4、in运算符:判断在不在某个对象中;
window.x=1;
'x' in window;//true
5、instanceof和typeof运算符:
{}instanceof Object; //true
typeof 100==='number'; //true
6、new运算符:
function Foo(){};//创建一个构造函数
Foo.prototype.x=1;
var obj=new Foo();
obj.x;
obj.hasOwnProperty('x'); //false 判断x是否为对象obj上的属性
obj._proto_.hasOwnProperty('x'); //true 判断x是否为原型链prototype上的属性
7、this运算符:
this; //全局作用域中this为window(浏览器)
var obj={
func:function(){
return this;
}
}
obj.func();//obj this为obj
8、void运算符:
void 0 //undefined
void(0) //undefined
注意:运算符优先级:
运算符 | 描述 |
. [] () | 字段访问、数组下标、函数调用以及表达式分组 |
++ -- - ~ ! delete new typeof void | 一元运算符、返回数据类型、对象创建、未定义值 |
* / % | 乘法、除法、取模 |
+ - + | 加法、减法、字符串连接 |
<< >> >>> | 移位 |
< <= > >= instanceof | 小于、小于等于、大于、大于等于、instanceof |
== != === !== | 等于、不等于、严格相等、非严格相等 |
& | 按位与 |
^ | 按位异或 |
| | 按位或 |
&& | 逻辑与 |
|| | 逻辑或 |
?: | 条件 |
= oP= | 赋值、运算赋值 |
, | 多重求值 |
六、try-catch语句:异常捕获机制
try{
throw 'test';
}catch(ex){
console.log(ex); //test
}finally{
console.log('finally');
}
执行流程:首先执行try块中的代码,如果抛出异常,就由catch捕获,并执行console,如果不发生异常,catch中的代码会被忽略掉,不管有没有异常,最后都会执行finally从句;注意:try后面必须接着一个catch或者finally从句;
try{
}finally{
console.log('finally'); //不管有没有异常,最终都要执行finally从句
}
try{
try{
throw new Error('oops');
}finally{
console.log('finally');
}
}catch(ex){
console.error('outer',ex.message); //执行结果为 finally outer oops,原因是因为内部的try中没有catch,就要执行离他最近的catch,但是内部的try中有finally,所以先执行finally,输出finally,然后再执行catch,输出outer,最后执行内部的try,输出oops;
}
try{
try{
throw new Error('oops');
}catch (ex){
console.error('inner',ex.message);
}finally{
console.log('finally');
}
}catch(ex){
console.error('outer',ex.message); //执行结果为 inner oops finally,原因是因为内部的try抛出oops异常后,首先执行内部的catch块,输出inner oops,然后再执行finally,输出finally,由于异常已经在内部处理过了,外层的try就不需要再执行异常了;
}
try{
try{
throw new Error('oops');
}catch(ex){
console.error('inner',ex.message);
throw ex;
}finally{
console.log('finally');
}
}catch(ex){
console.error('outer',ex.message);//执行结果为 inner oops finally outer oops,原因是因为内部try抛出oops异常之后,执行内部的catch,输出inner,但是内部的catch又抛出异常,输出oops,所以就到了外部的catch中,但是要执行外部的catch之前要执行内部的finally,输出finally,然后再输出outer,接着再输出oops;
}
七、对象:(js中出了基本类型就只有对象了)包含函数、数组、正则、日期等等;
1、对象中包含一系列的属性,并且属性都是无序的,每个属性有一个字符串的key和value,属性间用逗号隔开;
2、创建对象:
字面量方式:
var a={x:1,y:2,z:{a:2,b:4}};
new或原型链:
function foo(){} foo.prototype.z = 3; var obj =new foo(); obj.y = 2; obj.x = 1; obj.x; // 1 obj.y; // 2 obj.z; // 3 typeof obj.toString; // ‘function' 'z' in obj; // true obj.hasOwnProperty('z'); // false 判断是否含有prototype属性
Object.create方法:
var obj = Object.create({x : 1}); obj.x // 1 typeof obj.toString // "function" obj.hasOwnProperty('x');// false var obj = Object.create(null); obj.toString // undefined
3、对象属性删除:
注意以下属性不能被删除:
delete Object.prototype; //false
var 定义的全局变量或者局部变量、函数生命(无论是全局或者局部)都不能被delete掉,因为这些都不是对象的属性;但是隐式函数可以被delete;如下:
oh=1;
window.oh;//1
delete oh; //true
4、属性检测:
cat.hasOwnProperty('legs'); //true 判断cat是否含有legs属性;
cat.propertyIsEnumerable('legs'); //true 检测cat的属性是否可以被枚举
Object.defineProperty(cat,'price',{enumerable:false,value:1000}); //禁止cat属性被枚举 defineProperty:创建属性
cat.propertyIsEnumerable('price'); //false
5、get或者set方法读写属性:
var man = { name : 'Bosn', weibo : '@Bosn', get age() { return new Date().getFullYear() - 1988; }, set age(val) { console.log('Age can\'t be set to ' + val); } } console.log(man.age); // 27 man.age = 100; // Age can't be set to 100 console.log(man.age); // still 27
6、属性标签:
Object.getOwnPropertyDescriptor({pro : true}, 'pro'); //getOwnPropertyDescriptor()方法返回属性的标签
// Object {value: true, writable: true:是否可被修改, enumerable: true:是否可被遍历, configurable: true:其他属性标签是否可以暂被修改}
Object.getOwnPropertyDescriptor({pro : true}, 'a'); // undefined
7、对象序列化:
将json数据转为对象:JSON.stringify()
var obj = {x : 1, y : true, z : [1, 2, 3], nullVal : null}; JSON.stringify(obj); // "{"x":1,"y":true,"z":[1,2,3],"nullVal":null}"
obj = {val : undefined, a : NaN, b : Infinity, c : new Date()}; JSON.stringify(obj); // "{"a":null,"b":null,"c":"2015-01-20T14:15:43.910Z"}"
将对象转化为json:JSON.parse()
obj = JSON.parse('{"x" : 1}'); obj.x; // 1
八、数组:数组长度最长为2的23次方减1,即2^23-1,超过会报错;
1、创建数组:
new Array方式:
var arr = new Array();
var arrWithLength = new Array(100); // undefined * 100
var arrLikesLiteral = new Array(true, false, null, 1, 2, "hi"); // 等价于[true, false, null, 1, 2, "hi"];
【】方式:
var BAT = ['Alibaba', 'Tencent', 'Baidu'];
var students = [{name : 'Bosn', age : 27}, {name : 'Nunnly', age : 3}];
var arr = ['Nunnly', 'is', 'big', 'keng', 'B', 123, true, null];
var arrInArr = [[1, 2], [3, 4, 5]];
var commasArr1 = [1, , 2]; // 1, undefined, 2
var commasArr2 = [,,]; // undefined * 2
2、数组读写:数组从index=0开始,第一位的index=0;
delete a[0];console.log(a[0]); //undefined
3、数组元素处理:
arr.pop():将数组尾部的元素删除;
arr.push(3):从数组的尾部添加一个元素;
arr.shift():从数组的头部添加一个元素;
arr.unshift(0):将数组头部的元素删除;
var arr = [];
arr[0] = 1;
arr[1] = 2;
arr.push(3);
arr; // [1, 2, 3]
arr[arr.length] = 4; // equal to arr.push(4);
arr; // [1, 2, 3, 4]
arr.unshift(0);
arr; // [0, 1, 2, 3, 4];
delete arr[2];
arr; // [0, 1, undefined, 3, 4]
arr.length; // 5
2 in arr; // false
arr.length -= 1;
arr; // [0, 1, undefined, 3, 4], 4 is removed
arr.pop(); // 3 returned by pop
arr; // [0, 1, undefined], 3 is removed
arr.shift(); // 0 returned by shift
arr; // [1, undefined]
4.小注意:
①.+运算符注意:
a=+b;//这里的+b表示将b转换为number数字类型
a+=b;//这里的a+=b表示a=a+b,是在进行数字运算
②.isNaN:可以理解为首先NaN:not a number不是一个数字,而isNaN理解为:is not a number是否不是一个数字,因此在if判断中,isNaN为true,表示是 不是一个数字,也就是不是数字类型,而判断为false时,表示不是 不是一个数字,也就是是数字类型,因此isNaN判断为数字类型的布尔值应该为false;(注意NaN是数字类型)