javascript是一门动态脚本语言。通过原型链实现面向对象。
基础
数据结构
-
Numeber
-
bool
-
string
- 模板字符串
indexOf
substring
slice
(更灵活,可以使用负数作为参数)
-
Array
- 包含任意数据类型
- 可以随时给
length
赋值(不推荐) slice
push
和pop
unshift
(头部添加若干元素)和shift
(删掉第一个元素)sort
reverse
splice
concat
join
常用迭代方法:map
(映射)reduce
filter
:filter()
把传入的函数依次作用于每个元素,然后根据返回值是true
还是false
决定保留还是丢弃该元素。sort
(会直接对Array进行修改)every
:判断数组的所有元素是否满足测试条件。find
:查找符合条件的第一个元素。findIndex
:查找符合条件的第一个元素的索引。forEach
使用map
和reduce
将字符串转化成Number:
function string2int(s) {
var arr= Array.from(s).map(
x=>{
switch(x){
case '0': return 0;break;
case '1': return 1;break;
case '2': return 2;break;
case '3': return 3;break;
case '4': return 4;break;
case '5': return 5;break;
case '6': return 6;break;
case '7': return 7;break;
case '8': return 8;break;
case '9': return 9;break;
default: return null;
}
}
);
return arr.reduce((x,y) => x*10 + y);
}
- object : 由键值对组成的无序集合
var obj={
option1:{
x1:'996',
x2:'work'
},
option2:{
x1:'965',
x2:'life'
}
}
obj.option3;//undefined
obj.option3={
x1:'',
} //新增属性
obj.option3.x2='';//新增属性
delete obj.option1.x2;//删除option1属性(对象)中的x2属性
delete obj.option1;//删除option1属性
obj.option1;//undefined
delete obj['option3'];//另一种删除键值对的方式
'option2' in obj;//true
'option3' in obj;//false
'toString' in obj;//true 通过继承得到。 obj在原型链上指向`object`,所以拥有`toString`属性
obj.hasOwnProperty('option2');//true
obj.hasOwnProperty('toString');//false
在对象中绑定的函数称为这个对象的方法。
map
: ES6
JavaScript
的默认对象表示方式{}
可以视为其他语言中的Map
或Dictionary
的数据结构,即一组键值对。但是JavaScript
的对象有个小问题,就是键必须是字符串。但实际上Number
或者其他数据类型作为键也是非常合理的。
为了解决这个问题,最新的ES6规范引入了新的数据类型Map
。
set
: ES6set
是一组key的集合(不能重复)- 新建
set
时可以直接传入Array
作为输入
Set用于数组去重:
var arr=[1,2,2,3,5,6];
console.log("初始数组:"+arr);//1,2,2,3,4,5
var s=new Set(arr);
console.log(s);//1,2,3,5,6
var arr2=Array.from(s);
console.log("去重后的数组:"+arr2);//1,2,3,5,6
iterable
: ES6
Array、Map和Set都属于iterable类型。
具有iterable类型的集合可以通过新的for ... of循环来遍历。
语句
-
var
-
let
:块级作用域的变量。 -
const
:块级作用域的常量。 -
解构赋值
var {x, y, z} = {'hello', 'JavaScript', 'ES6'};
(如果x,y,z提前声明则要要将整条语句用小括号包裹,以免被当成块处理)- 使用的变量名可以和属性名不一致
{x,y,oldZ:Z}
- 可以使用默认值
{x,y,z=1}
- 使用场景:
- 交换
x
和y
的值:{x,y}={y,s}
- 快速获取当前页面的域名和路径:
var {hostname:domain, pathname:path} = location;
- 交换
- 使用的变量名可以和属性名不一致
-
for ... in
注意:Array
是一种对象,而它的每个元素的索引被视为对象的属性,因此,for ... in
循环得到的是Array的索引 -
for ... of
-
最好使用
forEach
方法 -
==
(相等运算符)和===
(严格运算符)
- 对于
string
,number
等基础类型,==
和===
是有区别的- 不同类型间比较,
==
之比较“转化成同一类型后的值”(自动调用toString
和valueOf
)看“值”是否相等,===
如果类型不同,其结果就是不等 - 同类型比较,直接进行“值”比较,两者结果一样(进行=比较,返回=的比较值)
==
不具有传递性- 如果两个值不具有相同类型,也有可能返回
true
- 如果一个值是
null
另一个值是undefined
,返回true
- 如果一个值是
string
另一个是number
,会把string
转换成number
再进行比较 - 如果一个值是
true
,会把它转成1
再比较,false
会转成0
- 如果一个值是
Object
,另一个是number
或者string
,会把Object
利用valueOf()
或者toString()
转换成原始类型再进行比较 Undefined
是基本类型,它转换成数字是NaN
,NaN
和谁对比结果都是false
,包括自己Null
是复合对象,它没有ValueOf()
和toString()
,它只有与undefind
和自己对比时结果是true
- 不同类型间比较,
- 对于
Array
,Object
等高级类型,==
和===
是没有区别的,进行的是“指针地址”比较- 要是两个值类型不同,返回
false
- 要是两个值都是
number
类型,并且数值相同,返回true
- 要是两个值都是
stirng
,并且两个值的String
内容相同,返回true
- 要是两个值都是
true
或者都是false
,返回true
- 要是两个值都是指向相同的
Object
,Array
或者function
,返回true
- 要是两个值都是
null
或者都是undefined
,返回true
- 要是两个值类型不同,返回
- 对于明确数据类型的用
===
更为可靠,JavaScript是一门弱类型语言,表达式运算赋值等操作都会导致类型转换。
函数
-
function func(x){}
-
var func=function(x){};
-
arguments
:永远指向当前函数的调用者传入的所有参数。(类似Array
但不是Array
) -
使用
rest
接受多余参数:function func(x1,x2,...rest){}
(rest
存放一个数组) -
利用
call()
、apply()
、bind
改变this
的指向
区别在于:Function.prototype.call(thisArg[, arg1, arg2, ...argN])
分别接受参数。Function.prototype.apply(thisArg [, argsArray])
接受数组形式的参数。call()
和apply()
都是立即调用。bind()
方法会创建一个新函数(将之作为返回值返回),称为绑定函数。当调用这个绑定函数时,绑定函数会以创建它时传入bind()
方法的第一个参数作为this
,传入bind()
方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
-
变量提升:JavaScript引擎会自动提升变量的声明,但不会提升变量的赋值;
-
全局变量会绑定到
window
上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,将自己的代码全部放入唯一的名字空间中以减少全局变量冲突的可能。 -
this
代表函数运行时,自动生成的一个内部对象,只能在函数内部使用,在函数执行时被绑定;- **如果没有用
obj.xxx()
的形式调用函数,this
会指向全局对象window
。(巨大的设计错误) var that = this;
所以有了这句话:调用方法前首先捕获this
。
- **如果没有用
-
JavaScript引擎有一个在行末自动添加分号的机制,小心
return
。
this这个 keyword非常的困惑,但是其实有一个好方法可以理解.
检查 ' . ' 左边是谁invoke 这个函数. 例如 xiaoming.age(); age函数里面有this, 然后 '. ' 旁边是xiaoming , 那么this就是指向xiaoming了.这种叫做 Implicit Binding.
如果点旁边没有,那就检查有没有用到 bind, apply, call 这三种, 有的话就是调用此方法的对象. 这种叫做 explicit binding.
如果上面两个都没有就检查代码里面有没有用到new 这个keyword, 有的话那就是指向new旁边的函数对象. 这种叫做new binding
上面三个都没有, 检查是不是有arrow function, 有arrow function的话就是, 那么指向是arrow function的lexical binding 的对象. 就是她的parent. 这种叫做 lexical binding
全部都没有如果不是strict mode那就是window对象了.. strict就是 error (undefined).