JavaScript补充

/* 阅读本文前,请先完整、粗略浏览一遍w3c Javascript教程*/

JS是动态弱类型语言,虽然实现声明变量,但是变量还可以赋值任何类型。
NaN和任何值都不等,和自己也不等,只能用Number.isNaN(NaN)判断
隐式转化:
遇到字符串一律拼接成字符串。
若没字符,转化成数字(bool类型是数字的子类型)
遇到undefined 转化成NaN
逻辑运算符、短路符 返回短路的类型,没有隐式转化

变量相关:

声明变量表示创建了变量,但还没赋值,此时值为undefined 。 var b
a = 150; //隐式声明, 有很大安全隐患,不推荐使用
var b = 200, e=50 ; // 只有var定义能在当前作用域提升此声明 。var变量先声明后初始化(赋值的意思),推荐使用var
let c =100 ; //let不能反复声明,但var可以。 let 作用域仅在当前语句块,注意是语句块。而var则是在全局或者当前函数体,看你在哪里声明定义这个变量。
var老语法,let新语法,只有新语法有语句块的概念
定义常量必须直接初始化(赋值) const d = 900;

switch 有穿透效果

一旦case 核对上但又没加break,后面的case也都执行,直到遇到break关键字。因此每句case都要加break。最后default语句都执行,不论顺序。

赋值语句的值:

在js中,赋值语句是有返回值的,不像python里那样。赋值语句的返回值就是右边表达式的结果。
js没有赋值即定义这种说法,如果你没有深入学过python可以忽略这段话。因此可以在函数里使用赋值语句 不会有影响。比如在函数返回使用:return a=b+1,则这个函数就返回b+1的值
假如有个函数add(a=1,b=2) {console.log(a,b)},默认参数a 为1,b为2,结果打印a和b
如果你在传参时写add(x=9,a=9) 会怎么样呢? 根据赋值语句的特性,这代码等同于add(9,9) ,因为赋值语句的返回值就是等号右边的值。

反引号可以支持多行,还支持插值 。

在这里插入图片描述
内部可以放变量、表达式,两边是反引号,不是单引号,反引号就是esc键下那个。

JS 解构

var [a,b,c=‘adf’] = [‘shenku’,‘s’] //数组解构,分别赋值给a,b;c因为拿不到,使用缺省值
对象属性使用{}来解构 : let {a,b}= obj ,并且靠名字对应而不是顺序对应
对象结构重命名 let {a:m,b:n}= obj ,以后使用a属性可以直接用m而不是obj.a
var arr = [1,2,3]
add(…arr) //参数解构,等同输入add([1,2,3])

逗号表达式

在这里插入图片描述
这里首先用数组解构为abc分别赋值1,2,3,d=0 ,猜猜最后控制台输出的值是什么?
这种形式称为逗号表达式(表达式1,表达式2,表达式3…)返回值为表达式最后一项,但是括号里的表达式都会依次执行。因此这里返回d++,而d++先用后增,最终输出0 。如果改成++d,则输出1
测试:
var [a,b,c] = [1,2,3]; var d=(a+1,b+2,c=9+3); console.log(d)最后输出什么?

答案是12,因为首先返回逗号表达式最后一项,最后一项是赋值语句c=9+3,而赋值语句的返回语句就是表达式右端的值,因此返回9+3
plus:JS中逗号 优先级低于等号。注意逗号表达式要用小括号括起来。

三元表达式语法: 条件?结果1:结果2

a===b?True:False
三元表达式和逗号表达式组合:
x= (a, b , a>b ? a+b : b++ )//逗号里按序执行,返回最后一项三元表达式的值,而三元表达式的值取决于a>b的结果
结果为4
结果为4

object和member

member和object是不同的, new出来的才是object,是类的实例。普通声明的变量的值是member
var a = new Array(1,2,3)// object
var a = Array(1,2,3) // member
实际使用中还没看出区别。。。稍作了解即可
数组可以 a = [1,2] ,或者 b = new Array() ,两种创建都是object

for in 和for of 语法:

var obj= {a:10, b:20}
for (let x in obj) console.log(x,obj[x])
for (let x of obj) console.log(x)
第一个in 语法 中x是索引,也就是obj的键;第二个of语法中的x是值。
obj改成数组也是同理,in 中的x表示索引,of中的x表示值

箭头表达式

/语法简单,推荐使用,并且以后在React中会大量使用这种语法/
(参数) =>{函数体} //整体作为一个函数返回
可以使用默认参数 (x,y=2)=>{return x+ y}
如果返回只有一行,可以用最简洁的形式:x=>x*2 ,但一旦有多行就要用花括号,有花括号就一定要有return关键字。
箭头函数经常搭配map、filter这些高阶函数使用
数组对象都有map方法 arr.map(x=>x +10),
arr.forEach(x=> newarr.push(x)) forEach 不返回,但是会遍历所有元素。forEach传入三个参数,第一个element 第二个index ,第三个array 本身。
逻辑复杂的话,一般用forEach 效率会好点。重复使用map和filter造成多次迭代。一定要用的话也要先filter再map 提升效率
arr.filter(x=> x>5)//筛选x>5的值
Object.keys(obj)
Object.assign({‘d’:100},obj,{‘f’:200})//重复的话就覆盖。 这个很常用

ES6不推荐使用解析式,生成器推荐使用生成器函数

生成器

生成器函数就是在函数体内有yield 关键字,函数便会惰性求值,使用时在function后面要加一个*
返回值依次1,2,3,undefined
b.next()返回值是一个{value:v, done:true}这样的对象,value的值依次是1,2,3,undefined
done的值为false,false,fasle,true

函数表达式中的函数名可以省略,写出来的话也只能使用在函数内部(递归函数使用)。
匿名函数就是没写名字的函数。和python别搞混。
const f1 = function f_name(x,y){return None} //带名字的函数,可以递归使用
const f2 = function (x,y){return None} // 匿名函数
每一个函数都有个arguments 的键值对字典,用于存放参数。

装饰器

装饰器是一个高阶函数(高阶函数即返回一个函数的函数,或者以函数为参数的函数。),装饰器用于加强函数。比如你写了一百个函数,现在你想在每个函数运行前打印一下是哪个函数在运行,或者在在函数结束前结束后记录一下运行时间,这些加强功能都可以在装饰器中实现。/* 可以先百度一下科里化的概念,帮助理解装饰器,在许多框架、语言的使用中,装饰器都是进阶必须掌握的部分。React的高级组件就会用到装饰器*/
这部分内容先搁置一下,改天补上
Promise 异步 同样暂时搁置。

其他

JS是基于原型的面向对象语言。原型对象是一个模板,新的对象从模板构建而获得属性,任何对象再运行时可以动态增加属性,而且任何对象可以作为另一个对象的原型,后者可以共享前者属性
构造器首字母大写
字符、数字、文本都能作为类的属性
要区分普通函数调用和类的调用
类的实例化要用new: a = new A(),否则funcition就是一次普通的函数调用
构造器首字母要大写,这是命名规范
function A(x,y){this.x = x, this.y = y }
继承:
继承的一种办法是使用父类的call:function B(x,y,z){A.call(this,x,y); this.z=2} // ES6之前用这个
ES6之后可以用class{constructor(x,y); show(){}}
class p3d extends p2d{super{}} //新语法的继承,新语法有些浏览器可能不兼容
必须使用super 不然使用this的时候会出错
调用时,方法或者属性同名时,属性优先,自身(和父类相比)优先,
继承只是使用父类的构造器来构造自己。
在方法前面定义static关键字 就是静态方法,实例无法调用,只有类能调用,和C++ JAVA一样。或者可以通过实例的construtor. 来访问
普通函数的this 指向全局,实例的函数执行this指向实例本身,调用call、apply 指向第一个值。
类外部不能用this
任何函数都有call方法,可以吧函数的this强行绑定。参数第一个是this。
apply效果和call一样,只不过传参apply用数组,除了this
bind返回的是一个函数,传统方法里最常用。
用了extends就一定要用super()
网页中this有bug,经常不知道指向谁,使用bind 可以明确绑定到一个对象上。
箭头函数已经解决this指定的问题了。但是ES6前后风格不要混写

猜你喜欢

转载自blog.csdn.net/qq_32835305/article/details/85036086