JavaScript深入浅出(进阶)

时间:2022-04-25 22:50:58

1、数据类型

js是弱类型,定义变量时不需要指定具体的数据类型,因此会出现一些奇妙的事情:

var num=23;   ---number类型
num="23";     ---string类型
"23" + 23 ;   结果为2323,string类型[字符串的连接 
"23" - 23     结果为0,number类型[如果有一个操作数是字符串,先将其转换为数值,再执行减法运算] 

六种数据类型:

1)原始类型:number、string、boolean、undefined、null  

2)对象:object( Function、Array、Date...)


2、隐式类型转换

若要将string->number :   - 0 (减去 0)

number -> string :   + ''  (加上空串'')


3、包装对象

 var str = "string" ; ---string类型
 var strObj= new String(" string" ); ---String类型
为什么string类型可以有属性(如length)? 因为在调用时系统自动将其转换为object类型,结束后销毁(还原)

 

4、类型检测

1) typeof

2) instanceof ---obj instane Object

[2,3] instanceof Array === true


  JavaScript深入浅出(进阶)

3) Object.prototype.toString

 

Object.prototype.toString.apply([]) === "[objectArray]"

4)constructor

5) duck type         适用参考来源       类型转换超难【不会】例子

JavaScript深入浅出(进阶)

5、运算符      来源

1) ,逗号运算符:从左往右依次运算,结果为最右边的运算值

2) delete运算符:删除值 

3)  in/

6、语句

1) 在for(var i=0)中定义的i是全局变量,不是块级作用域

2) try catch/finally

3) 函数声明: var fun=function(){ ...//}   function fun(){   ...//变量提升,会 先执行 } 

4) for in 受原型链影响: var p; var obj={x:1 , y:3};   for( p  in  obj)

5) with 修改作用域

6) 'use strict' 严格模式

JavaScript深入浅出(进阶)

JavaScript深入浅出(进阶)

7、对象

1)定义

方式一: var obj={x:1 ,y:2 ,z:{a:1 ,b:2} };
方式二(  new/原型链 )

2)对象结构

JavaScript深入浅出(进阶)

JavaScript深入浅出(进阶)

3)原型链当定义一个函数(function fun),都会自动有一个原型属性(prototype)

JavaScript深入浅出(进阶)

JavaScript深入浅出(进阶)

JavaScript深入浅出(进阶)

当定义一个新的对象时,在本对象查找不到属性,会沿着原型链往上查找

 

方式三( Object.create):  var obj=Object.create({x:1 ,y:2});

 

4)属性操作 :  读写对象属性、属性异常、删除属性、检测属性、枚举属性

<1>属性读写方式一:

var obj={x:2 ,y:3};
obj.x;  --2    //两种方式
obj["y"]; ---3

<2>属性读写异常

JavaScript深入浅出(进阶)

<3>属性删除:delete obj.x ;

<4>属性检测:son in obj ;   ---返回true/false    (会沿着原型链向上查找)

  obj.hasOwnProperty(" son");  ---自身对象

  obj.propertyIsEnumberable(" son");  ---是否可以被枚举

  Object.defineProperty( obj , "son" ,{ enumerable : true ,value : 23} );   ---定义属性和原型链上的属性

-obj.hasOwnProperty(" son");  ---自身对象
obj.propertyIsEnumberable(" son");  ---是否可以被枚举
Object.defineProperty( obj , "son" ,{ enumerable : true ,value : 23} );  ---定义属性和原型链上的属性 参数:对象,属性,原型链上的属性
JavaScript深入浅出(进阶)  一知半解:移驾

属性读写方式二:getter/setter

var person={ name:"cheng" ,get age(){ return 23;} ,set age(val){ ..} };
console.log(person.age); ---23 自动调用get age()方法 

 

5)属性标签:

Object.getOwnPropertyDescriptor( { obj: ' test'} , "obj" ) ;   ---参数: 对象,属性

 JavaScript深入浅出(进阶)JavaScript深入浅出(进阶)JavaScript深入浅出(进阶)


对象标签:[[ proto ]] 、[[ class ]] 、[[ extensible ]]

<1>原型标签 [[ proto ]]

<2>对象类型标签[[ class ]] 

var toString=Object.prototype.toString;
function getType(obj){ return toString.call(obj).slice(8,-1);  } 
 //调用获取对象类型的方法,并截取其中的有效数据 , 从第8位开始倒数第2位(去掉[object ])
toString.call(null);  ---"[object Null]" 
getType(null);   ---"Null"
getType(1);  ---"Number"

JavaScript深入浅出(进阶)

<3>对象(的属性)可扩展标签 extensible 

object.preventExtensible(obj); //使obj对象不可新增属性,原属性可改、可删 Object.seal(obj); //使obj不可新增属性,原属性可改但不可删 Object.freeze(obj); //使obj不可新增属性,原属性不可更改、删除

JavaScript深入浅出(进阶)

6)序列化:将数据变为字符串形式
var obj={ x:1 ,y: true ,z: [1,2,3] ,t: undefined };  JSON.stringify(obj);    //将js对象序列化---后端 可用
//   "{ "x" :1 , "y" :true ,"z" :[1,2,3] } "   --undefined直接被舍弃
obj=JSON.parse( '{"x":1 }' );  // obj.x=1 ,将字符串转化为js对象

序列化自定义
var obj = {     x : 1,     y : 2,     o : {         o1 : 1,         o2 : 2,         toJSON : function () {             return this.o1 + this.o2;         }     } }; JSON.stringify(obj); // "{"x":1,"y":2,"o":3}" 


8、数组


1)值的有序集合。弱类型,每个值可以是不同的类型。也可以是数组

var obj=[ 1, null ,true ,[3,2] ];   ---obj[3][1]=2  

2)创建  

 var arr=[1,,3];  var  arr=[1,,];   ---空为undefined ,默认最后一个可为,  var arr2 = new Array(100);  ---创建100个空值数组 var arr2 = new Array(1,2,3) ;  ---值为1,2 ,3

3)读写

var arr=[1,3];
arr[2]=true; ---动态添加第三个数true 
arr.length=3;
delete arr[0]; --删除第一个数据,变为空值"",数组长度不变
arr.length-=1; //通过将数组长度-1,可以动态删除最后一个数据
arr.push(23); 最后位置插入一个值23 
var lastNum=arr.pop(); 最后一位数据删除并返回
arr.unshift(23); 首部位置插入一个值23
var firstNum=arr.shift(); 第一位数据删除并返回

JavaScript深入浅出(进阶)

4)二维数组

var arr=[[1,2],[2,3],[3,4,5]];
for(var i=0;i<arr.length;i++){
	var arr2=arr[i];
	for( var j=0;j<arr2.length;j++){
		console.log(arr2[j]);
	}
}

5)稀疏数组:不含有从0开始的连续索引,一般length值比实际元素个数大

var arr1 = [undefined]; var arr2 = new Array(1); 0 in arr1; // true var arr=[,,]; 0 in arr2; // false 0 in arr; //false arr1.length = 100;  arr1[99] = 123; 99 in arr1; // true 98 in arr1; // false


6)数组方法--原型方法 Object.prototype


var arr=[1,2,3];
arr.join("_");  ---转化为字符串,有参数则为连接符  :1_2_3  ;无参即为 1,2,3
例:function repeatString(str, n) {	//快速定义一个重复数组的字符串
     return new Array(n + 1).join(str);  	//长度为n+1,中间的连接为n个
}    
repeatString("a", 3); 	// "aaa" [undefined,undefined,undefined,undefined] 	
repeatString("Hi", 5); 	// "HiHiHiHiHi"

arr.reverse();  ---反序排列数组  : 3,2,1 (原数组被修改)

arr.sort(); ---字母顺序排序
var arr = ["a", "d", "c", "b"];
arr.sort();  // ["a", "b", "c", "d"]

arr = [13, 24, 51, 3];
arr.sort(); // [13, 24, 3, 51] 
arr;  // [13, 24, 3, 51] ---将第一个去做了比较 
arr.sort(function(a, b) {   //自定义排序函数        //带参数的排序w3c来源
     return a - b; 
});  // [3, 13, 24, 51]
arr = [{age : 25}, {age : 39}, {age : 99}];
arr.sort(function(a, b) {
     return a.age - b.age;
});
arr.forEach(function(item) {
     console.log('age', item.age);
}); // result:  age 25、age 39、age 99

arr.concat(2,3); --数组合并
var arr = [1, 2, 3]; arr.concat(4, 5); // [1, 2, 3, 4, 5] arr; // [1, 2, 3] ---原数组没有被修改 arr.concat([10, 11], 13); // [1, 2, 3, 10, 11, 13] --参数是数组,会被拉平一次  arr.concat([1, [2, 3]]); // [1, 2, 3, 1, [2, 3] 

arr.slice(2,5); --数组截取 ,参数为索引, [2,5) ,最后一位索引也是 -1
var arr = [1, 2, 3, 4, 5]; arr.slice(1, 3); // [2, 3] --原数组没有被修改  arr.slice(1);   // [2, 3, 4, 5] arr.slice(1, -1); // [2, 3, 4] arr.slice(-4, -3); // [2] 

arr.splice(2); --数组拼接/删除 
var arr = [1, 2, 3, 4, 5]; var arr2 = arr.splice(2);  // returns [3, 4, 5] arr;  // [1, 2]; --原数组被修改 arr = [1, 2, 3, 4, 5]; arr.splice(2, 2); // returns [3, 4] 参数:索引,想删除的元素个数 arr; // [1, 2, 5]; arr = [1, 2, 3, 4, 5]; arr.splice(1, 1, 'a', 'b'); //returns [2] 参数:第三个开始是要添加的值,再删除的位置开始添加、拼接 arr;   // [1, "a", "b", 3, 4, 5] 

arr.forEach( function( x , index){ ...} ); --数组遍历 函数为参数,x为值、index索引 IE 9+
var arr = [1, 2, 3, 4, 5];
arr.forEach(function(x, index, a){
    console.log(x + '|' + index + '|' + (a === arr));
}); // 1|0|true // 2|1|true // 3|2|true // 4|3|true // 5|4|true 

arr.map( function(x) { ...} ); ---数组映射,在数组的基础上做一些变动 函数为参数,x为值
var arr = [1, 2, 3];
arr.map(function(x) {
     return x + 10; });  // [11, 12, 13] arr;  // [1, 2, 3] --原数组没有被修改 

arr.filter( function( x , index){ ...} ); --数组过滤、筛选 函数为参数,x为值、index索引
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; arr.filter(function(x, index) {      return index % 3 === 0 || x >= 8; });  // returns [1, 4, 7, 8, 9, 10] arr;  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ---原数组没有被修改 

arr.every/some( function(x) {  ...} ); 
 //数组判断,是否符合条件,every代表每一个值(x);some代表至少存在一个值满足条件
var arr = [1, 2, 3, 4, 5]; var arr = [1, 2, 3, 4, 5]; arr.every(function(x){  arr.some(function(x) {    return x<10;   return x === 3; });  //true   }); // true  arr.every(function(x){  arr.some(function(x) {    return x<3;   return x === 100; }); //false   }); // false 

arr.reduce/reduceRight( function(x) {  ...} ); 数组中的值两两进行操作、判断
var arr = [1, 2, 3]; var sum = arr.reduce(function(x, y) {      return x + y;   //第一个参数为函数,第二个为第一个参数的x;若没有,则x是数组第一个数, }, 0); // 6  y为第二个数 arr; //[1, 2, 3] --原数组未被修改 arr = [3, 9, 6]; var max = arr.reduce(function(x, y) {      console.log(x + "|" + y);      return x > y ? x : y; }); // 3|9 9|6 9 max; // 9 
max = arr.reduceRight(function(x, y) { //判断的顺序从后 往前      console.log(x + "|" + y);      return x > y ? x : y; }); // 6|9  9|3 max: 9 

arr.indexOf/lastIndexOf(3); //数组检索 ,last..从后往前找,返回的都是坐标(最后一位索引-1 )
var arr = [1, 2, 3, 2, 1]; arr.indexOf(2);  // 1 --查找2 arr.indexOf(99);  // -1 --没找到 arr.indexOf(1, 1);  // 4 --查找1,从索引1(第二个数)开始查找 arr.indexOf(1, -3);  // 4 arr.indexOf(2, -1);  // -1 arr.lastIndexOf(2);  // 3 arr.lastIndexOf(2, -2);  // 3 arr.lastIndexOf(2, -3);  // 1 

Array.isArray([]);  true  ---判断是否为数组
[] instanceof Array; // true
({}).toString.apply([]) === '[object Array]'; // true
[].constructor === Array; // true 


数组与字符串
var str = "hello world";
str.charAt(0); // "h" 
str[1]; // e    --一般不用这样(数组方法操作字符串)

Array.prototype.join.call(str, "_");  //利用数组方法操作字符串
// "h_e_l_l_o_ _w_o_r_l_d"

9、函数(对象)

js中,函数也是对象,可以像其他对象操作与传递。

1)调用:
<1>直接调用:foo();
<2>对象方法:o.method();
<3>构造器:new Foo();
<4>call/apply/bind : func.call( o );

2)定义: 
<1>函数声明方式: 
function fun(){  ...};     //作用全局,声明会提前到最开始

<2>函数表达式方式:    ---具体移驾
var fun=function(){  ...};   //函数变量
(function(){  ...})();      //立即执行
return function(){  ...};   //作为返回值
var fun=function another(){  ...};  //命名式函数

<3>函数构造器
var fun = new Function('a','b',' console.log(a+b); ');   //fun(1,2); =3
var fun = Function('a','b',' console.log(a+b); ');  //最后一个为函数体,前面都是参数
JavaScript深入浅出(进阶)

10、this    我也还不懂

1)全局的this---浏览器
this.document===document;
this===window
this.a=37;
window.a ;    ---37

2)一般函数的this---浏览器
function fun(){   return this; }   fun()===window;   --严格模式下为undefined

3)作为对象方法的函数 this---对象

4)作为对象原型链上的this  ---?

var o={ f : function() { return this.a + this.b } };
var p= Object.create( o );
p.a=1;
p.b=4;
console.log( p.f() );   //5  --this 可以取到 p.a  

5)get/set 与 this

6)构造器中的this
JavaScript深入浅出(进阶)

7)call/apply方法的this

JavaScript深入浅出(进阶)

8)bind方法与this      
JavaScript深入浅出(进阶)

11、函数属性和arguments   --bind/call/arguments


1) fun.name 函数名

2) fun.length 形参个数

3) arguments.length 实参个数


12、闭包   ---参考:详解


JavaScript深入浅出(进阶)

13、作用域


JavaScript深入浅出(进阶)

JavaScript深入浅出(进阶)


14、OOP--面向对象编程


1) 基于原型的继承:每个 函数(对象)声明后都有一个原型属性:prototype
2) 原型和prototype属性:prototype是每个对象都会有的一个属性,通过这个属性可以有很多的方法

JavaScript深入浅出(进阶)


JavaScript深入浅出(进阶)


JavaScript深入浅出(进阶)