JavaScript知识点整理(一)

JavaScript知识点(一)包括 数据类型、表达式和运算符、语句、对象、数组。

一、数据类型

1) js中6种数据类型:弱类型特性
    5种原始类型:number(数字)、string(字符串)、boolean(布尔值)、null 、undefined
    1种对象类型:object对象(函数function 数组array 日期Date等)
2)数字转换字符串可以的+"",字符串转换数字可以-0
例:var num = 32;
num = "this is a string"
32 + 32 //结果为64
"32" + 32 //结果为"3232" (会被认为字符串拼接)
"32" - 32 //结果为0 (被认为数字相减)

3)等于与严格等于:

严格等于===:
如果两边类型不同,直接返回false
类型相同:
null===null
undefined===undefined
NaN≠NaN (NaN不等于任何,包括本身)
new object≠new object (js中对象是通过引用来比较而不是通过值比较)
等于==:
若类型相同,同===
若类型不同,尝试类型转换和比较:
如:
null==undefined相等
number==string 会尝试把字符串转换为数字 1=="1.0"//true
boolean==? 会将boolean转换为数字,true转成1,false转成0 1==true//true
object==number|string会尝试把对象转为基本类型 new string("hi")=="hi"//true
其他情况:false
  例: "1.23"==1.23
0==false
new Object()==new Object()
[1,2]==[1,2]
4)javascript包装对象
javascrpt隐藏机制:当把一个基本类型以对象的形式去使用的时候,javascript会将其转换为包装类型对象,相当于new一个string .
但是当操作完毕后这个临时包装对象就会被销毁,无法调用。

例:
var a="string";
a.length;//6
a.t=3;
alert(a.t);//undefined
当尝试以对象的方式使用一个string/number/boolean基本类型的时候,
比如访问这个字符串的length属性或增加一个属性,JavaScript只能把这个基本类型转换成包装类型对象。
当设置完成后,这个临时对象会被销毁掉。所以再次访问该属性,就是undefined。
演示效果:

 

二、表达式和运算符

1)表达式:

1. 原始表达式 //常量、直接量、关键字、变量 3.14、"test"、null、i、k、j
2. 数组、对象的初始化表达式 //[1,2]、{x:1, y:2}
 [1, 2] 等价于 new Array(1, 2);
 [1, , , 4] 等价于 [1, undefined, undefined , 4]
 {x:1,y:2}等价于
 var o=new Object();
 o.x=1;o.y=2;
3. 函数表达式 //var fe = function(){}、(function(){})() 
4. 属性访问表达式 //var o = {x:1}、o.x、o['x']
5. 调用表达式 //func()
6. 对象创建表达式:
var temp=new Func(1,2)//有参数,没有参数时也可以把括号直接去掉
var temp=new Object;//没有参数
2)运算符
特殊运算符的种类:
1、条件运算符 c?a:b c为true 则取a,否则取b
2、逗号运算符 a,b 例如 var s = (1,2,3),则s依次赋值,最后输出为3
3、delete运算符 delete obj.x 删除对象obj中的x属性 在IE9下,obj中必须configurable:true 才可以删除,否则无效
4、in运算符 判断obj是否有值或window里是否有变量,返回布尔值 例如 attr in json 或 'document' in window
5、instanceof 判断对象类型 {} instanceof Object // true(返回布尔值)
6、new运算符 创建一个新对象 new obj / new array ...
7、this对象 全局用指向window,函数内指向函数本身,浮动指针
8、typeof 判断对象,返回对象类型 例如 typeof 100 === 'number' // true(判断对应类型字符串)
9、void 一元的,判断所有值,返回均为undefined
一般delete 运算符可以删除对象的属性,而如果使用方法Object.defineProperty(对象,'属性',{configurable:false})处理了对象,该属性就不会被删除,反之ture就是可以被删除

三、语句

1) 以{}组成块block,常用于for循环和if判断语句中,要注意没有块级作用域,比如for循环中var i=0;写在()内和写在for循环外面是一样的;还是属于全局变量;
在函数内定义 var a=b=1;会隐式定义出全局变量b;在函数外获取不到a,为undefined,但可以获取到b,a=1,b=1解决
在ES6面试之后有了let,即开始有了块级作用域。
var声明变量:
var a=1;
var a=b=1;
function  fuc(){
  var a=b=1;
}
func();
console.log(typeof a)//undefined  局部变量 外部不可访问
console.log(typeof b)//number  (隐式创建了全局 变量)

2)

try - catch - finally 语句:
1.使用throw 抛出的异常,需要被catch 处理,无论是否有catch 处理,都会执行finally 
2.若嵌套try - catch - finally 语句,先看内层 throw 的error 是否被内层的catch处理,否则则被外层 catch 处理。
3.若内层 catch 处理时,也throw 了 error,则外层catch 仍会处理。否则,外层catch 不执行。
4.try语句如果抛出异常,则执行catch语句,否则不执行,无论有没有异常,都执行finally语句;try语句必须跟catch或finally语句中至少一个组合使用。
try catch语句的嵌套语句执行顺序: 1)如果内部嵌套的try语句抛出异常,但内部没有相配套的catch语句,先执行内部的finally语句,然后跳到最近一层的catch语句执行。 2)如果内部嵌套的try语句抛出异常,内部有相配套的catch语句,先执行此语句处理异常,再执行内部的finally语句。不会再在外部处理异常。 3)如果内部嵌套的try语句抛出异常,内部有相配套的catch语句,并且catch语句也抛出异常,如果内部的catch语句有对异常的处理,
先执行异常处理语句,然后执行内部的finally语句,最后执行离内部catch语句抛出异常最近一层的catch语句处理异常。

3) 

function fun() 这个叫函数声明,会预先处理,所以调用能写到声明前面。
var fe = function(){}则不可以。
1、for in遍历的时候,顺序不确定,如果要按顺序显示,不要用for in
2、enumerable(枚举)为false时不会出现
3、for in对象属性时受原型链影响,如果原型链上有其他值,也会在for in 的时候出现。

4)严格模式
JS的严格模式:
定义和优点:严格模式是一种特殊的执行模式,它修复了部分语言上的不足(禁用with),
提供了更强的错误检查(重复属性,删除delete不可配置的属性等),并增强了安全性(在eval中使用独立作用域等); 模式的使用: (1)function func(){'use strict';}好处:向上兼容 (2)'use strict'; function func(){}指定整个js内的代码都是在严格模式下 与普通模式的区别: 在严格模式下:①不允许使用with;
②不允许未声明的变量被赋值
③arguments变为参数的静态副本,不管参数传与不传,对arguments无影响,但是对象的属性除外;
④delete参数,函数名报错
⑤delete不可配置的属性报错
⑥对象字面量重复属性名报错
⑦禁止八进制字面量
⑧eval,arguments变为关键字,不能作为变量、函数名
⑨eval变为独立作用域,其它地方不可以拿到eval的值;


四、对象

1.对象:对象中包含一系列的属性,这些属性是无序的,每个属性都有一个字符串key和对应的value;
var obj ={ x:1,y:2};
obj.x;//1
obj.y;//2
2.对象构造:
除了本身被赋予的值之外,对象还有几个隐藏标签:
proto:对象的对象属性prototype上的赋值,每一个对象都有一个原型[prototype]                            
class:对象的种类,表示属于哪一个类
extensible:表示是否允许该对象继续增加新的属性
另外对象的值(如 x=1),也有对应的属性或方法,提供一些访问权限的控制
writable:是否可写
enumerable:是否能被删除
configurable:是否能够枚举
value:值
get/set:
3.创建对象的方法:
1) 对象字面量
     var obj1 = { x:1 , y:2);
2) new/原型链
     function foo(){}
     foo.prototype.z=3;
     var obj = new foo();
注意:给对象赋值时,并不会去查找原型链,仅在该对象内查找,有则覆盖,无则创建。
如:
1、obj.z=5;-->若给obj赋值,并不会去原型链上查找,会看obj上是否有这个值,有就能修改,没有就仅在当前对象添加值
2、delete obj.z后,通过obj.z访问到的是原型上的z;delete obj.z只能delete当前对象的属性而不会去影响到原型链
obj.z = undefined; 并不一定代表 obj 上没有z属性,可能是有,其值为undefined。 如果想继续使用原型链上的z ,
需要delete obj.z 用直接赋值法创建对象时,对象的属性可以通过hasOwnProperty和in(in会向上找到原型链)来判断是否是对象本身中的属性,还是对象自己添加的属性。
注意:对象自己添加的属性可以通过delete来删除,但不能用delete删除原型上的属性。
同时,发现一个属性值为undefined不一定是这个值未定义,也有可能是有这个属性,其属性值就是undefined


3)var obj = Object.create({x:1})
Object.create:
var obj = Object.create({x:1}); Object.create()是一个系统内置的函数,其参数通常为一个对象,
该方法返回一个新创建的obj对象,并且该obj对象的原型指向这个参数对象,而参数对象原型指向Object.prototype。 并不是所有的对象都有.toString()方法,因为不是所有的对象的原型链上都有Object.prototype属性 例: var obj = Object.create(null); obj.toString // undefined

 

4.属性操作
1) 用for-in遍历时,原型链上的属性也会被遍历到,而且是无序遍历。
2) 属性删除用delete, prototype属性不可被删除;
var定义的变量也不可用delete删除,函数也不可以被delete掉
(经验证,不同的内核实现方式不同,在chrome下不可被delete掉,返回false,但在firefox和IE10下可以被delete掉,返回true,对于函数也是相同的结果) eval()里面用var定义的变量可以用delete删除。
3)configurable:是否可配置。getOwnPrototypeDescriptor(属性所在的对象,属性名)
4)in操作符会向原型链向上查找的,hasOwnProperty 是检测对象在排除原型链的情况下是否具有某个属性(用在for in判断过滤原型上的属性)。
5)Enumerable:是否可枚举。 
6)Object.defineProperty自定义对象属性(参数:属性所在的对象,属性名,描述符对象)
   Object.defineProperty(obj,"price",{enumerable:false,configurable:false,value:1999})//
   obj.hasOwnProperty("price")//判断是否是自身属性
   obj.propertyIsEnumerable("price")//判断是否可枚举
7)!=undefined就是不等于null和undefined
8)delete 可以删除对象的属性,删除不了全局变量和局部变量,隐士声明全局变量和在eval 中声明的变量可以删除
注意:
判断某个属性是否存在与某个对象中,可以通过in运算符,hasOwnProperty()和propertyIsEnumerable()方法来完成.
in运算符,如果对象的自有属性或继承属性中包含这个属性,则返回true.
对象的hasOwnProperty()方法用来检测给定的名字是否是对象的自有属性.
propertyIsEnumerable()是hasOwnProperty()的增强版,只有检测到时自有属性且这个属性的可枚举性为true时才能返回true.

5.get/set方法
var obj = new foo();
obj.z; //1 
obj.z = 10;
obj.z;// still 1
如果对象的原型链上有 z 属性,且z 属性有 get/set 方法,则不会直接在obj 上添加 z 属性,而是使用 obj的原型链上的get/set 方法。
此种情况下希望在 obj 上添加 z 属性,需要使用defineProperty()方法,此方法默认所有标签为false
若以后需要delete obj 上的z 属性,需把configurable:true


例:
val = +val; 一元操作符的使用,让传入的值转换成相应的数字,如果原来就是数字或者转换成功,则后续操作就用数字进行,如果转换失败,将返回NaN...

 

6.属性标签

Object.getOwnPropertyDiscriptor(obj,"x")//获取对象的属性标签
修改多个属性标签
Object.defineProperties(obj,{
title:{value:"xxx"},
name:{configurable:true}
sex:{
get:function(){
                return "nan"
              }
     }
}
);
标签属性:
configurable :是否可以配置属性,可以用来设定是否能够删除
writable:设置是否可以写入,可以用来设定是否能够进行重新赋值
enumerable:设置是否可以进行枚举
value:指定默认值

 


7.对象标签、标签序列化
1)对象标签:
[[proto]]:原型链
[[class]]:toString
[[extensible]]:表示对象的属性是否可以添加。
object.preventExtensible(obj);//使obj对象不可新增属性,原属性可改、可删
Object.seal(obj);//使obj不可新增属性,原属性可改但不可删
Object.freeze(obj);//使obj不可新增属性,原属性不可更改、删除
注意,当Object.freeze(obj)后,Object.isSeal(obj)返回的也是true,也就是说,Object.isSeal(obj)返回true,其原属性也可能不可改。
2)序列化
通过全局的JSON.stringify(obj);做序列化处理
注意:
1、当你对象中有属性的值是undefined的时候,这该属性是不会出现在序列化字符串的结果里
2、当你属性的值是NaN或者Infinity时,序列化的结果是null;当你的属性值是new Date(),序列化的结果是UTC的时间格式
后端返回JSON数据,则用JSON.parse来转化;合法的JSON的属性必须用双引号引起来

五、数组

1) 创建数组、数组操作
1、JS中的数组是弱类型的 数组中可以含有不同类型的元素 数组元素甚至可以是对象 或者其他数组; 2.创建 2.1 字面量 var arr = ['ds','aa']; 2.2 new Array构造器 var arr = new Array(); var arr = new Array(10); 则表示该数组有10个空元素(只有一个值的时候表示有多少元素) var arr = new Array('a','b'); 等价于 ['a','b']; new 是可以省略的 3.数组的读写 数组元素增减 用delate可以删除元素,但是数组长度不变,其实delate之后,是设置元素的值为undefined。 arr.push(1); 在数组尾部添加元素 arr.unshift();在数组头部添加元素 delete arr[2]; 是将数组中的下标为2的元素 变成undefined 并非真正的删除 arr.pop() 删除数组的最后一个元素 arr.shift() 删除数组的第一个元素
数组的最大长度是2^23-1
delete 直接删除和直接赋值为undefined是不一样的,
delete后 arr[i] in arr; --->false
赋值undefin后 arr[i] in arr; --->true
4.数组迭代 for循环 for in 遍历(定义在原型上的属性也会遍历出来) 使用hasOwnProperty可以避免将原型上的属性遍历出来
for(i in arr){
if(arr.hasOwnProperty(i))
//不会遍历出原型上的元素
}

2)二维数组、稀疏数组

1.二维数组,就是一维数组的元素是数组,所以通过一维数组下标只是找到了子数组,要想访问子数组的元素,还需要子数组的下标。
所以要想访问二维数组元素,外层数组名[外层数组下标值][字数组下标值]
2.稀疏数组,下标不是从0开始,长度length大于实际数组元素个数。

var arr = [undefined]; 这个是给位置0设置了undefined,
而 var arr = new Array(99) ,虽然给数组安排了99个位置,但是这99个位置占了但是里面没有内容。

简单的说就是如果那个位置有值的话用in判断就返回true,反之则返回false。
var arr = new Array(100);
arr[98] = 123;
98 in arr;  //true : 98上key值存在
97 in arr;  //false :: 97上key值不存在
稀疏数组:
1. var arr1=[undefined];//有第0个元素,为undefined
2. var arr2=new Array(1);//稀疏数组,数组长度为1,但并没有定义arr[0]
3. var arr3=[,,];//稀疏数组,定义了两个个undefined数组元素,没有规定arr[0]就是undefined

所以,0 in arr1//return true(表示key 0 是否在arr1中); 0 in arr2//return false;
arr1.length = 100; arr1[99]=123; 99 in arr1//return true; 98 in arr1//return false(因为arr[98]并没有被定义)
凡是没有显示定义数组索引的,都是稀疏数组
3)数组方法
join()--将数组转换为字符串,可打印数组。
join("")给数组添加组合符号。如arr=[a,b,c];arr.join("_");//"a_b_c",原数组未被修改
reverse()倒序排列数组。注意原数组会被修改
sort()按照字母的顺序排序,但是无法满足复杂的字符串,即无法按数字大小排序
sort(function(a,b){return a-b})---在sort方法中定义一个函数,如果是升序排列的话,前面的值要小于后面的值,就要返回一个负数;
如果是降序排列的话;前面的数会大于后面的数,返回一个正数。注意原数组会被修改。 concat()合并数组,不会修改原数组 slice(a,b)表示截取数组第a个索引元素到第b个索引元素结束,左闭右开;当a,b值为负数时,表示倒着截取数组,且不对原数组修改。 splice(a)只有一个参数时,表示在a索引的位置截断数组,形成两个数组; splice(a,b)有两个参数时,表示在a索引的位置截取b个元素形成新数组。 splice(a,b,新元素) splice方法原数组会被修改。
数组的方法(ES5的方法)
1.forEach  遍历
2.map 映射
var arr = [1,2,3];
arr.map(function(x){
return x +10;
});//【11,12,13】
arr;//[1,2,3]
原数组未被修改

3.filter 数组过滤
arr = [1,2,3,4,5,6,7,8,9,10];
arr.filter(function(x,index){
return index%3 ===0 || x>=8;
});   [1,4,7,8,9,10];
arr; 原数组未被修改

4. 数组判断
 every  所有的元素都符合条件 返回true  否则返回false
 some   某个元素符合条件则返回true  若所有的元素都不符合条件则返回false
var arr =[1,2,3];
arr.every(function(x){
return  X<10;
});//true

arr.every(function(x){
return x < 3
});//false
6.reduce 数组中的元素两两之间的某些操作 从左到右 reduceRight 从右往左 var arr = [1,2,3]; var sum = arr.reduce(function(x,y){ return x+ y },0);//6 传入了一个0 则x相当于0 y 相当于1 然后值1 ;
然后此时 x 相当于1 y 相当于2 和为3 x相当于3 y 相当于3 和为6 所以结果为6 如果不传入0这个值 则X从数组的第一个元素开始 循环两两元素相加 reduceRight 同理 只不过是从右往左开始两两操作 7.indexOf 数组的检索 indexOf(a,b);a 是查找的元素 b是开始查找的位置 正数从左数的位置 负数从右数的位置 indexOf(元素); 返回的是元素的下标 不存在返回-1 lastIndexOf 从右往左查。
8.判断是否是数组,有 4 种方法:
1)Array.isArray(arr)
2)arr instanceof Array 3)Object.prototype.toString.apply(arr)
4)arr.constructor === Array
数组和对象的区别
相同点:1.都可以继承。
       2.数组是对象,对象不一定是数组。
       3.都可以当作对象添加删除属性。
不同点:1.数组会自动更新length。
       2.索引访问数组比访问一般对象属性迅速。
字符串类似数组,可以通过索引访问字符串中的元素,但是没有数组中的一些操作方法,字符串可以通过如下的方式使用join()方法:
使用"_"来连接字符串:Array.prototype.join.call(str,"_");


posted @ 2017-02-25 10:35  Lovebugs.cn  阅读(216)  评论(0编辑  收藏  举报