一、前端技术

1、HTML

HTML(hypertext markup language)超文本标记语言,不同于编程语言。

超文本就是超出纯文本的范畴,描述文本的颜色、大小、字体。

HTML由一个个标签组成,标签各司其职,有的提供网页信息,有的负责图片,有的负责网页布局。

超文本需要显示,就得有软件呈现超文本定义的排版格式,,例如显示图片、表格、显示字体的大小,颜色,软件就是浏览器。

超文本的诞生是为了解决纯文本不能格式显示问题,是为了好看,但是只用通过网络分享超文本的内容,所以制定了HTTP协议。

2、浏览器

1)历史、1980年代,tim berners-Lee为cern设计基于超文本思想的enquire,以促进科研人员之间信息更新和共享。19899年其编写了《信息化管理;建议》一文,并构建基于Internet的hypertext系统,并在cern开发了world wide web项目。打造了世界上第一站。于1991年8月6日上线。

Tim berners-lee于1990年发明了第一个浏览器,还发明了HTTP协议。

1994年MIT创建了w3c。w3c万维网联盟,负责万维网持续发展,提出w3c的标准应该基于无专利权、无版税。

Marc Andreessen于1993年发明了mosaic浏览器,看到了技术前景,不久后成立自己的公司---网景公司Netscape,1994发不了Netscape navigator浏览器,席卷全球。

1995年微软发布IE。

1999年网景被aol收购,收购后,Netscape公开了浏览器代码。创建了Mozilla组织。Mozilla组织使用gecko引擎重写浏览器。。

2003网景被解散。

2008年google的Chrome浏览器待着v8引擎横空出世。

2)网景公司

HTTP cookie,解决HTTP无状态。

Javascript

Ssl协议:

Jar格式文件,将Java的class文件打包压缩,并加上签名。

2012年4月9日,微软购买800项美国在线的专利或专利授权。

3)浏览器技术

浏览器是特殊的客户端。

浏览器软件分为两个部分

         外壳:

外壳提供用户交互的界面。

内核(引擎engine)

提供HTML,css,图像的渲染引擎。提供DOM编程接口。

提供Javascript引擎。

排版(渲染)引擎

浏览器

说明

Gecko

Firefox

Trident

IE,AOL

Khtml

Presto

oPera

Webkit

Safari,Chrome

Blink

Chrome,Opera

Js引擎:

Jscript、tracemonkey(firefox)  v8等

使用jquery等框架来解决兼容性问题。

3、js

是一种动态的弱类型的脚本解释性语言。和HTML、css秉承三大web核心技术。

4、ES

ECMAscript:是ecma国际组织

JavaScript是商品名。

2009年 ES5发布

2015年ES6发布

5、v8引擎

谷歌推出的,使用的是bsd协议开源。

二、nodejs

1、nodejs简介

Nodejs是服务器端运行JavaScript的开源、跨平台运行环境。

作者是瑞安达尔(ryan dahl),2009年发布,使用了v8引擎,采用时间驱动,非阻塞,异步IO模型。

2012年,npm软件包管理器诞生,通过其,可以方便的发布,分享nodejs的库和源代码。

Nodejs4.0引入了ES6语言的特性。

2、安装

国内阿里云镜像

https://npm.taobao.org/mirrors/node

Linux:

https://npm.taobao.org/mirrors/node/latest-v8.x/node-v8.11.3-linux-x64.tar.xz

windows:

https://npm.taobao.org/mirrors/node/latest-v8.x/node-v8.11.3-x64.msi

默认路径安装:

3、开发

Visual studio code

https://code.visualstudio.com/Download

4、注释

和c、Java一样

//单行注释

/*comment*/ 
多行注释,在语句中间使用。

str = 'hello' + /*comment*/ 'student'

5、常量和变量

标识符

标识符必须是字母、下划线、美元符号和数字,但必须是字母、下划线、美元符号开头。,不能是数字开头。

标识符区分大小写。

声明

var 
a声明   a值为undefined   声明全局变量

let 
b 声明   let  块变量,局部变量。

const 
c常量声明时候必须赋值。后期不允许更改。明确知道一个标识符定以后不在膝盖,声明的时候使用const常量,减少被修改的风险。

能给常量就不用变量。

变量和常量声明和初始化的过程中是可以分开的。

var a

let b

console.log(a,b)

a = 1

b = 'a string'

console.log(a,b)

//const c   //不能定义,因为const定义时候必须赋值,之后不可以再次进行更改

const c = 100

console.log(c)

var y //只是复制,y的值为undefined

var x = 1 //规范的声明并初始化,声明全局或局部变量

function hello()

{

var a    //只是声明,a为undefined,作用域是在函数中

a = 100   //赋值

}

//console.log(2,a)   //抛出错误,变量a未定义

//a = 200   //不能提升作用域

//var a = 200;hello();   //var提升作用域

//console.log(3,a)

6、数据类型

序号

名称

说明

1

number

数值型

2

boolean

布尔型,true和False

3

String

字符串

4

Null

只有一个null值

5

Undefined

变量声明未赋值的

6

Symbol

Es6新引入的类型

7

object类型

以上基本类型的复合类型,容器

ES是动态弱语言,弱类型语言,虽然先声明了变量,但是变量可以重新赋值任何类型。

//string

console.log('----string-------')

console.log(a = 3+'abc',typeof(a))

console.log(a = null + 'abc',typeof(a))

console.log(a = undefined + 'abc',typeof(a))

console.log(a = true + 'abc',typeof(a))

//number

console.log('----number----')

console.log(a = null + 1,typeof(a))

console.log(a = undefined + 1,typeof(a))   //undefined没有办法转成对应的数字,只是显示男,not a number

console.log(a = true + 8,typeof(a))

console.log(a = false + 8,typeof(a))

//boolean

console.log('----bool----')

console.log(a = null + true,typeof(a))

console.log(a = null + false,typeof(a))

console.log(a = undefined + true,typeof(a))   //undefined没有办法转成对应的数字

console.log(a = undefined + false,typeof(a))  //undefined,不能转成对应的数字

console.log(a = null & true,typeof(a))

console.log(a = undefined & true,typeof(a))

//短路

console.log(a = null && true,typeof(a))

console.log(a = false && null,typeof(a))

console.log(a = false && 'abc',typeof(a))

console.log(a = true && 'abc',typeof(a))

console.log(a = true && '',typeof(a))

//null

console.log(a = null + undefined,typeof(a))

----string-------

3abc string

nullabc string

undefinedabc string

trueabc string

----number----

1 'number'

NaN 'number'

9 'number'

8 'number'

----bool----

1 'number'

0 'number'

NaN 'number'

NaN 'number'

0 'number'

0 'number'

null 'object'

false 'boolean'

false 'boolean'

abc string

string

NaN 'number'

类型运算:

String:与str相加全部转化为str类型。

Number:与number相加全部转化为number

Boolean类型:转为话number类型

弱类型,不需要强制类型转换,会隐士的类型转换。

总结:

遇到字符串,加号就是拼接字符串。

如果没有遇到字符串,加号就是把其他的所有的类型都当做数字处理。

Undefined特殊,因为他没有定义值,所以是一个特殊的数字nan.

如果运算符是逻辑运算符,短路符,返回的就是短路时候的类型,没有隐士转换,

尽量使用显示的转换。

7、字符串

将一个值利用单引号或者双引号引起来就是字符串。

Es6提供了反引号定义一个字符串,可以支持多行,还可以支持插值。

字符串:插值。使用反引号$符号进行插值,赋值即定义。

let a = 'abc'

let b = 'ced'

let c = `line1

line2

line3

`

console.log(c)

let name = 'tom',age = 19

console.log(`hi name is ${name},age${age}`)

line1

line2

line3

hi name is tom,age19

8、转义字符

名称

说明

\0

Null字节

\b

退格符

\f

换页符

\n

换行符

\r

回车符

\t

Tab制表符

\v

垂直制表符

\’

单引号

\”

双引号

\

反斜杠符(\)

\XXX

由从0到377最多三位八进制数XXX,例如\251是版权符号的八进制序列

\xXX

由从00和FF的两位十六进制数字XX表示的Latin-1字符。\ x A9是版权符号的十六进制序列

\uXXXX

由思维十六进制数字XXXX的Unicode字符,例如,\u 00A9是版权符号的Unicode序列。见Unicode escape sequences(Unicode转义字符)

\u{XXXXX}

Unicode代码点(code point)转义字符,例如\u{2F804}相当于Unicode转义字符\uD87E\uDc04的简写。

9、字符串操作方法

let a = 'abcdefgh'

console.log(a.charAt(2))    //索引查找字符串

console.log(a[2])        //索引查找字符串

console.log(a.toUpperCase())  // 大写

console.log(a.concat('.com'))  
//拼接字符串

console.log(a.slice(3))     
//  切片

console.log(a.slice(3,6))    //

console.log(a.slice(-2,-1))   //负索引切片

console.log(a.slice(-2))    //负索引切片

c

c

ABCDEFGH

abcdefgh.com

defgh

def

g

gh

let url = 'www.google.com'

console.log(url.split('.'))   //以什么进行切割

console.log(url.substr(7,2))   //
返回字符串从何处开始,取多长

console.log(url.substring(7,10)) 
// 返回子串,从何处开始,到什么为止

[ 'www', 'google', 'com' ]

gl

gle

let url1 = 'www.google.com'

console.log(url1.indexOf('com'))     
//   查找字符串所在的索引

console.log(url1.replace('.com','.cn'))   //替换

console.log(url1.indexOf('gle',3))   
//   向右偏移3

url2 = '\tmg edu \r\n'

console.log(url2.trim())       //去除两端的空白字符串

11

www.google.cn

7

mg edu

10、数值型number

在js中,数据均为双精度浮点型范围只能在- +(2^53-1)之间,整型不例外。

数字类型还有三种符号值:+infinity(正无穷)  -infinity(负无穷)和nan(not-a-number非数字)

二进制0b。

八进制0o

十六进制0x

指数表示1E3(1000),2e-2(0.02)

常量属性:

数字的方法;

方法

描述

Number.parseFloat()

把字符串参数解析成浮点数,和全局方法parseFloat()作用一致

Number.parseInt()

把字符串解析成特定基数对应的整型数字,和全局方法parseInt()作用一致

Number.isFinite()

判断传递的值是否为有限的数字

Number.isInteger()

判断传递的值是否为整数

Number.isNaN()

判断传递的值是否为NaN

内置数学对象:Math

有绝对值,对数、指数运算、三角函数运算、最大值、最小值、随机数、开方等运算函数。

console.log(Math.PI)    //3.14 PI值

console.log(Math.abs(-1))   //绝对值

console.log(Math.log2(16))   // 开方

console.log(Math.sqrt(2))    //平方根

console.log(Math.random())    //随机数

11、运算符

1)算数运算符

+ - * / %

console.log(1/2)   //0.5

console.log(1/0)  //Infinity

console.log(5%3)   //2

console.log(parseInt(1/2))     // 
0  向下取整

console.log(parseInt(3/2))     // 1  
向下取整

console.log(Math.floor(3/2))   // 1  
向下取整

console.log(Math.ceil(3/2))    // 2  
向下取整

console.log(Math.round(3/2))   // 
2  四舍五入

console.log(Math.round(1/2))   // 
1  四舍五入

++和—

单目运算符,表示变量自增,自减

I++ 先用i,用完之后在加1

++I i先自增,在使用i

let i = 0

let a = i++

console.log(a,i)   //0  
1

console.log(a,i++)   // 0  
1

a = ++ i

console.log(a,i)    // 3 
3

单目运算符是优先级高于双目运算符。

7

i = 0;

let a = ++i+i+++i+++i; //++i + i++ i++ +i

console.log(a);        //  1  
1   2    3  7

2)比较运算符

不做隐士的类型转换写的是===。

不做两个等等号。严格相等使用三个等号。

console.log(100  > '200') //  false

console.log(100 > 'a')   //false

console.log(300 == '300')  //true

console.log(300 === '300')  //false

3)逻辑运算符

&&,||,!  与或非

4)位运算

& | 
^ ~<< >>位与,位或,异或,取反,左移,右移。

5)三元运算符

条件表达式?真值:假值

console.log(('3' > 30)?'真':'假')

6)逗号操作符

Js运行多个表达式写在一起

let a = 4+5,b = true,c=a > 20?'t':'f'

console.log(a)   // 9

console.log(c)    // f

7)其他

名称

说明

Instanceof

判断是否属于指定类型

Typeof

判断类型字符串

Delete

Delete操作符,删除对象

In

判断指定的属性在对象内,则返回true

console.log('a' instanceof String) 
// false

console.log(1 instanceof Number)   
// false

a = new String('b')

console.log(a instanceof String) 
// true

console.log(new Number(1) instanceof Number) // true

console.log(a instanceof Object) // true

Instance必须明确使用的类型定义变量。没有 new方法的类型的都不是初始的类型。可以用于继承关系的判断。

Typeof就是返回对象的类型字符串。

Delete删除对象、属性、数组元素

8)运算符优先级

运算符由高到低。

var trees = new Array();

逗号运算符优先级最低,比赋值语句还低。

9)表达式(生产器)

function* inc()

{

let i = 0;

let j = 2;

while(true){

yield i++

if (!j--)return  100;

}

}

let gen = inc()

for (let i = 0 ;i<10;i++)

console.log(gen.next());

{ value: 0, done: false }

{ value: 1, done: false }

{ value: 2, done: false }

{ value: 100, done: true }

{ value: undefined, done: true }

{ value: undefined, done: true }

{ value: undefined, done: true }

{ value: undefined, done: true }

{ value: undefined, done: true }

{ value: undefined, done: true }

每次调用next()方法返回一个对象,这个对象包含两个属性:value和done,value属性表示本次yield表达式的返回值,done属性为布尔值,done是False表示后续还有yield语句执行,如果执行完成或者return后,done为true。

三、js语法

1、语句块

function hello(){

let a = 1;

var b = 2;

c =3

}

if (1)

{

let d = 4;

var e = 5;

f = 6

if (true){

console.log(d)

console.log(e)

console.log(f)

console.log('------')

g = 10

var h = 11

}

}

console.log(e)

console.log(f)

console.log(g)

console.log(h)

4

5

6

------

5

6

10

11

大括号中都是一个作用域。

Let定义的外部不能访问,只能是内部才能访问。Var块作用域,外部可以见到,普通定义外部也可见。

2、条件分支

if (cond1){

}

else if(cond2){

}

else if (cond3){

}

else{

}

条件False等效

False

Undefined

Null

0

NaN

空字符串(””)

3、switch..case分支语句

switch (expression){

case label_1

statements_1

[break;]

case label_2

statements_2

[break;]

default:

statements_def

[break;]

}

let x = 5

switch (x){

case 0:

console.log('zero')

break;

case 1:

console.log('one')

case 2:

console.log('two')

case 3:

console.log('three')

break;

case 4:

console.log('four')

default:

console.log('other')

break;

}

Switch…case语句都可以协程多分支结构。

4、for循环

//for ([initialExpression];[condition];[increamentExpression])

//{

//  statement

//}

for (let i=0;i<10;i++){

console.log(i)

}

console.log('---')

5、while循环和do….while循环

While (condition)

Statement

条件满足,进入循环,条件为真,继续循环

do

statement

while (condition);

先进入循环,然后判断,为真就继续循环。

let x = 10;

while(x--){

console.log(x);

}

do{

console.log(x);

}while(x++<10)

打印九九乘法表:

for (let x =
1;x<10;x++)

{

line = '';

for(let y = 1;y<=x;y++)

line += `${x}*${y}=${x*y}`;

console.log(line)

}

5、for…in 循环

对象操作语句for…in用来遍历对象的属性

for (variable in object){

statements}

let arr =[10,20,30,40 ]

console.log(arr[2])  
//30

for (let x in arr)

console.log(x)

for (let index in arr)

console.log(`${index}:${arr[index]}`);

for (let i=0;i<arr.length;i++)

console.log(arr[i]);

let obj = {

a:1,

b:'abc',

c:true

};

console.log(obj.a)

console.log(obj['b'])

console.log(obj.d)

console.log('++++++')

for (let x in obj)

console.log(x) 
//属性名

for (let key in obj) 
//返回数组的index

console.log(`${key}:${obj[key]}`);

30

0

1

2

3

0:10

1:20

2:30

3:40

10

20

30

40

1

abc

undefined

++++++

a

b

c

a:1

b:abc

c:true

for in 循环返回的是索引或者key,需要简介访问到值。

数组反正返回的是索引,c风格for循环操作简单。

6、for..of循环

Es6的新语法

let arr =
[1,2,3,4,5]

let obj = {

a;1,

b:'abc',

c:true

}

for (let i of
arr){  //返回数组的元素

console.log(i)

}

for (let i of
obj){  //异常,不可以迭代

console.log(i)

}

For….of不能是迭代对象。

原因是of后面必须是一个迭代器(typeerror)

break 、continue

break结束当前循环

continue中断当前煦暖,直接进入下一次循环。

7、for迭代的差别

function sum(arr){

for (let x in arr){

console.log(x,typeof(x),arr[x]);

}

for (let x of arr){

console.log(x,typeof(x));

}

for (let x =
0;x<arr.length;x++){

console.log(x,typeof(x),arr[x])

}

}

X退出的时候还是会加一或减一。

四、函数及作用域

1、函数表达式

function //函数名(参数列表){

//函数体;

return //返回值;

}

function add(x,y){

return x + y

}

console.log(add(3,5))

匿名函数表达式

const add = function(x,y){

return x + y;

};

console.log(add(4,5))

有名字的函数表达式

const add1 = function fn(x,y){

return x + y;

};

console.log(add1(3,4))

有名字的函数表达式,名字只能内部使用,外部不可见

const add2 = function _add(n){

if (n === 1) return n;

return n+ _add(--n)

};

console.log(add2(5))

函数、匿名函数、函数表达式的差异

函数和匿名函数,本质上是一样的,都是函数对象,不过函数都有自己的标识符,函数名,匿名函数需要的是借助其他的标识符而已。

区别在于,函数会声明提升,函数表达式不会。

console.log(add(3,4))

function add(x,y){     //声明提升

return x + y;

};

console.log(sub(4,5))   //会报出异常的,提示sub未定义

const sub = function(x,y){

return x + y;

};

定义函数的形式:function表达式。(有名字和匿名的),有名字的内部使用等。

声明先做,调用后做。

生成器:

const counter = (function *(){

count = 1

while(1)

yield count ++;

})();

console.log(counter.next())

2、高阶函数

高阶函数:函数作为参数或者返回一个函数。

const counter = function(){

let c = 0;

return function(){

return c++

};

};

const c = counter()

console.log(c())

console.log(c())

map函数的实现

const map = function(arr,fn){

newarr = []

for (i in arr){

newarr[i] = fn(arr[i])

}

return newarr

};

console.log(map([1,2,3,4],function(x){

return ++x

}));

3、箭头函数

const map1 = function(arr,fn){

newarr = []

for (i in arr){

newarr[i] = fn(arr[i])

}

return newarr

}

console.log(map([1,2,3,4],x =>++x))

// console.log(map1([1,2,3,4],x =>++x))

// console.log(map1([1,2,3,4],x=>{return ++x}))

console.log(map1([1,2,3,4],(x)=>{return ++x}))

箭头函数就是匿名函数定义。

去掉关键字function。

一个参数的时候可以省掉括号。无参和多参数的时候必须保留括号。多个参数使用逗号分隔。

有大括号的时候必须有return。

定义是定义的形式。调用必须加括号,因为有优先级的问题,所以调用前面的利用括号抱起来。

箭头函数的返回值:

如果函数体部分有多行,就需要使用{},如果有返回值使用关键字return。

如果只有一行语句,可以同时省略大括号和return。

只要有return语句,就不能省略大括号,有return必须有大括号。

只有一条非return语句,加上大括号,函数就是没有返回值了。

Map函数:

function map(arr,fn){

newarr1 = []

for (i in arr)

newarr1[i] = fn(arr[i])

return newarr1

};

console.log(map([1,2,3,4],function(x){

return ++x;

}));

4、参数

传参是按照位置对应的,没有关键字传参这个属性。写的像的话只是赋值语句。

传参的是只是表达式的值。

数组不解构的话当做一个来进行,解构利用…

缺省值可以进行定义的。位置传参的,缺省值往后写

//位置传参

const add = (x,y)=> x+y;

console.log(add(4,5));

//缺省值

const add1 = (x,y=6)=>x+y;

console.log(add1(4))

//非关键字传参,没有关键字传参,只是表达式

const add2 = (x,y)=>x+y;

console.log(add2(z=1,c=2))

//缺省值不能放在前,否则就是转换为3和undefined相加,加过为NaN

const add3 = (x=1,y)=>x+y;

console.log(add3(3))    //NaN

5、可变参数

(1)args

const sum = function(...args){

let resule = 0;

for (i in args){

resule += args[i]

};

return resule

};

console.log(sum(2,3,4))

可变参数使用…args.

(2)arguments对象

const sum = function(...args){

let resule = 0;

console.log(arguments)

for (i in args){

resule += args[i]

};

return resule

};

console.log(sum(2,3,4))

{ '0': 2, '1': 3, '2': 4 }

所有的参数会保存到一个k,v,键值对的字典里面。

(3)参数解构

const add = function (x,y){

return x+y

}

console.log(add(...[100,200,300,400,500]))   //参数解构,不需要参数一一对应的。

参数解构,不需要和需要的参数一一对应。

6、返回值

Return的返回值:返回的通常是几个参数,返回的是最后一个参数的值。逗号表达式的。

const add1 = (x,y)=>{return x,y}

console.log(add1(1,2))

表达式的值:

逗号表达式,最后一个的值。

返回 的都只是一个单值。

a = (x = 5,y=6,true);

console.log(a)

b = (x=1,y=4,'abc');

console.log(b)

function c() {

return x= 1,y=2,'abc',false;

}

console.log(c());

7、作用域

Function函数定义,是独立的作用域,内部定义的变量外部不可以见到。

//函数作用域

function c(){

a = 1

var b = 2

let c1 = 3

};

c();

console.log(a)

//console.log(b)   //  函数中var定义变量没有方法突破,外界见不到

//console.log(c1)  //   let定义的外界见不到

//块作用域

if (1){

d = 4

var e = 5

let f = 6

}

console.log(d)

console.log(e)       //var 块中定义的才会外界可以见到。

// console.log(f)      //let定义外界始终见不到

var b = 2可以提升声明,可以突破非函数的块作用域。

a = 1 隐士声明不能进行提升声明,

let a=3不能提升声明。

严格模式:使用”use strict”语句放到函数的首行,或者js脚本首行。

function show(i,args){

console.log(i,args)

};

x = 100;

function fn(){

let z = 200;

{

var a = 300;

show(1,x)

t = 'free'

let p = 400;

}

var y = 500

show(2,z)

show(3,x)

show(4,a)

show(5,t)

//show(5.5,p) //异常,let出不来上一个语句块

{

show(6,y);

show(7,a)

show(8,t)

{

show(9,a)

show(10,t)

show(11,z)

}

}

}

fn()

// show(12,y)   //异常,出不了函数的y

show(13,t)

// show(14,a)   //异常,a不能出函数的

show(15,z)  
//变量声明提升,声明了z,但是还没赋值

var z = 10;

五、js对象模型

基于原型的面向对象语言,而不是基于类的面向对象语言。

基于对象事件。

Js是基于原型的语言,只有原型对象的概念,原型对象就是一个模板,新的对象从这个对象模板构建从而获取最初的属性,任何对象在运行时候可以动态的增加属性。任何一个对象都可以作为另一个对象的原型,后者就可以共享前者的属性。

1、定义类

var obj = {

}

var obj1 = new Object();

var obj2 = new Object;

创建的时候必须使用new方法。

function定义的时候 大驼峰。

字面声明方式。

2、es6之前---构造器

function Point(x,y){

this.x = x

this.y = y

this.show = ()=>console.log(1,this,this.x,this.y)

};

console.log(Point)

p1 = new Point(4,5)

console.log(2,p1)

function Point3D(x,y,z){

Point.call(this,x,y);

this.z = z

console.log(3,'Point 3d')

};

console.log(4,Point3D)

p2 = new Point3D(3,4,5)

console.log(5,p2)

p2.show();

[Function: Point]

2 Point { x: 4, y: 5, show: [Function] }

4 [Function: Point3D]

3 'Point 3d'

5 Point3D { x: 3, y: 4, show: [Function], z: 5 }

1 Point3D { x: 3, y: 4, show: [Function], z: 5 } 3 4

(1)定义一个函数(构造器)对象,函数名首字母大写。

(2)This指代是当前实例的本身。定义属性。

(3)使用new和构造器创建一个通用对象。New操作符会将新的对象的this值传递给point3d构造器函数,函数为这个对象创建z属性。

如果不使用new方法,就是普通的函数调用,this不代表实例。

3、es6中的class

(1)class

Es6开始,提供了关键字class,创建对象更加简单、清晰。

(1)利用关键字class,创建的本质上还是一个函数,是特殊的函数。

(2)一个类只能拥有一个名为constructor的构造器方法,如果没有显示定义一个构造方法,,就会默认添加一个constructor方法。

(3)继承使用extends关键字

(4)一个构造器可以使用super关键字来调用父类的构造函数。

(5)类没有私有属性。

class Point{

constructor(x,y){

this.x = x

this.y = y

}

show(){

console.log(this,this.x,this.y)

}

}

let p1 = new Point(10,11)

p1.show()

class Point3D extends Point{

constructor(x,y,z){

super(x,y);

this.z = z

}

}

let p2 = new Point3D(4,5,6)

p2.show()

Point { x: 10, y: 11 } 10 11

Point3D { x: 4, y: 5, z: 6 } 4 5

重新写show方法;

class Point{

constructor(x,y){

this.x = x

this.y = y

}

show(){

console.log(this,this.x,this.y)

}

}

p1 = new Point(1,2)

console.log(p1)

class Point3D extends Point{

constructor(x,y,z){

super(x,y)

this.z= z

}

show(){

console.log(this ,this.x,this.y,this.z)

}

}

p2 = new Point3D(3,4,5)

console.log(p2)

子类中直接重写父类的方法即可,如果需要使用父类的方法,使用super.method()的方式调用。

使用箭头函数修改:

class Point{

constructor(x,y){

this.x = x

this.y = y

this.show = ()=>console.log('point')

}

}

//继承关系

class Point3D extends Point{

constructor (x,y,z){

super(x,y,z)

this.z = z

this.show=()=>console.log('point3d')

}

}

let p2 = new Point3D(3,4,5);

p2.show()

point3d

子类覆盖,最终显示的结果是point

class Point{

constructor(x,y){

this.x = x

this.y = y

this.show =()=>

console.log('point')

}

}

class Point3D extends Point{

constructor(x,y,z){

super(x,y)

this.z = z

//this.show=()=>console.log('Point3d')

}

show(){

console.log('point3d')

}

}

优先使用实例的方法,show方法,使用this的方法。

class Point{

constructor(x,y){

this.x = x

this.y = y

//this.show =()=>

//  console.log('point')

}

show(){

console.log(this,this.x,this.y)

}

}

class Point3D extends Point{

constructor(x,y,z){

super(x,y)

this.z = z

this.show=()=>console.log('Point3d')

}

//show(){

// console.log('point3d')

//}

}

let p1 = new Point3D(2,3,4)

console.log(p1)

p1.show()

属性优先,一定先用属性。优先使用子类的属性。

总结:如果子类和父类使用同一种方式进行定义,子类覆盖父类的。

如果父类使用的属性,子类使用的是方法,那么就是采用父类的属性。

如果子类使用的属性,父类是方法,那么优先使用的是子类的属性方法。。

最终总结,属性优先。。同一类定义的,子类优先

静态属性:

静态方法没有很好的支持的。

(2)静态方法:

在方法名前面加上static,就是静态方法了。

class Add{

constructor(x,y){

this.x = x

this.y = y

}

static show(){

console.log(this.x)  //this是Add   不是Add的实例

}

}

a = new Add(2,3)

console.log(a)

//a.show()    实例不能直接访问静态方法

a.constructor.show()  //实例可以通过constructor构造器方法访问静态方法。

静态方法总结:实例不能直接访问静态方法,实例必须通过constructor方法访问静态方法。

静态成员必须使用类来定义的。

实例是自己的。

4、this的坑

var shcool = {

name : 'abc',

getNameFunc: function(){

console.log(1,this.name)

console.log(2,this)

return function(){

console.log(3,this === global);

return this.name

}

}

};

console.log(4,shcool.getNameFunc()());

this是全局的global的,所以第三行是true。

第四行,This是global的,所哟下面的return this.name没有name属性。

函数调用的时候调用的方式不用,this的对象就是不同的。

函数执行的时候,会开启新的执行上下文环境executioncontext。

创建this属性。

(1)myfunction(1,2,3)普通的函数调用,this指向的是全局对象,全局对象是nodejs的global或者浏览器的window。

(2)myObject.myFunction(1,2,3),对象的方法调用方式,this指向包含该方法的对象。

(3)call和apply方法的调用,都要看第一个参数是谁。

解决this的问题。

1)显式传入

var shcool1 = {

name : 'cde',

getNameFunc1 : function(){

console.log(this.name)

console.log(this);

return function(that){

console.log(this === global);

return that.name;

}

}

}

console.log(shcool1.getNameFunc1()(shcool1))

cde

{ name: 'cde', getNameFunc1: [Function: getNameFunc1] }

true

cde

利用关键字that   传入对象。主动传入对象,避开了this的问题

2)引入call、apply方法。

var shcool2 = {

name : 'asd',

getNameFunc2:function(){

console.log(this.name)

console.log(this);

return function(){

console.log(this === global);

return this.name

}

}

}

console.log(shcool2.getNameFunc2().call(shcool2));

asd

{ name: 'asd', getNameFunc2: [Function: getNameFunc2] }

false

asd

call方法和apply都是函数对象的方法,第一参数都是传入对象引入的。

Apply传其他参数需要数组。

Call传其他参数需要使用可变参数收集。

3)bind方法

var school3 = {

name: 'asdd',

getNameFunc3:function(){

console.log(1,this.name)

console.log(2,this)

return function(){

console.log(3,this === global);

return this.name;

}

}

};

// console.log(school3.getNameFunc3().bind(school3));

var func = school3.getNameFunc3()

console.log(4,func)

var bindfunc = func.bind(school3)

console.log(5,bindfunc)

console.log(6,bindfunc())

1 'asdd'

2 { name: 'asdd', getNameFunc3: [Function: getNameFunc3] }

4 [Function]

5 [Function: bound ]

3 false

6 'asdd'

Apply、call方法,参数不同,调用时候传入this。

。bind方法是为函数绑定this,调用时候直接调用

4)es6引入的箭头函数定义

var school = {

name :'ass',

getNameFunc:function(){

console.log(this)

console.log(this.name)

return ()=>{

console.log(this === global);

return this.name

}

}

};

console.log(school.getNameFunc()())

{ name: 'ass', getNameFunc: [Function: getNameFunc] }

ass

false

ass

class school{

constructor(){

this.name = 'abcd';

}

getNameFunc(){

console.log(this.name)

console.log(this);

return ()=>{

console.log(this === global);

return this.name

}

}

};

console.log(new school().getNameFunc()())

abcd

school { name: 'abcd' }

false

abcd

绑定之后返回一个新的函数。

全局对象。

全局global,

浏览器中叫做window

解决this语法的利用bind。

5、高阶对象、高阶类、或称为Mixin模式

Mixin,混合模式,不用继承就可以复用的技术,主要还是为了解决多重继承的问题,多继承的路径是个大问题。

Js是基于对象的,类和对象都是对象模板。

混合Mixin,指的四将一个对象的全部或者部分拷贝到另一个对象上去,其实就是属性了。

可以将多个类或对象混合成一个类对象。

指的是将一个对象的全部或者部分拷贝到另一个对象上去。

返回的是定义的类。

class Serialization{

constructor(){

console.log('serialization construtor---');

if (typeof(this.stringify) !== 'function'){

throw new ReferenceError('should define stringify')

}

}

}

class Point extends Serialization{

constructor(x,y){

console.log('Point constructor');

super()

this.x = x

this.y = y

}

stringify(){

return 
`<point x=${this.x},y=${this.y}>`

}

}

class Point3d extends Point{

constructor(x,y,z){

super(x,y);

this.z = z

}

stringify(){

return `<point x=${this.x},y=${this.y},z=${this.z}>`

}

}

p = new Point(4,5)

console.log(p.stringify())

p3d = new Point3d(7,8,9)

console.log(p3d.stringify())

Point constructor

serialization construtor---

<point x=4,y=5>

Point constructor

serialization construtor---

<point x=7,y=8,z=9>

高阶对象实现,将类的继承构建成为箭头函数

//普通继承

class A extends Object{};

console.log(A)

//匿名类

const A1 = class{

constructor(x){

this.x = x;

}

}

console.log(A1)

console.log(new A1(100).x)

//匿名继承

const B = class extends Object{

constructor(){

super()

console.log('B constorse')

}

};

console.log(B)

b = new B()

console.log(b)

[Function: A]

[Function: A1]

100

[Function: B]

B constorse

B {}

Point3d调用父类serialization,此类然后调用继承point类。

尽量少的改变原有代码的方式增强注入函数的功能。Extends继承,就是Mixin类,混入的类型。

React框架大量使用了Mixin类。

const x = (Sup) =>{

return class extends Sup{

constructor(){

super();

console.log('c constructor')

}

}

};

const c = Sup =>class extends Sup{

constructor(){

super();

console.log('c constorce')

}

};

cls = c(A)

console.log(cls)

a = new cls();

console.log(a);

const Serialization = Sup => class extends Sup{

constructor(...args){

console.log('serialization constructor--')

super(...args);

if (typeof(this.stringify)!=='function'){

throw new ReferenceError('should define stringify')

}

}

}

class Point{

constructor(x,y){

console.log('point constrouct')

this.x =x

this.y =y

}

}

class Point3d extends Serialization(Point){

constructor(x,y,z){

super(x,y)

this.x = x

}

stringify(){

return `<point3d ${this.x}.${this.y}>`

}

}

let p3d = new Point3d(1,2,3)

console.log(p3d.stringify())

serialization constructor--

point constrouct

<point3d 1.2>

Serialization(point)实际上是匿名函数的调用,返回一个新的类型,point3d继承来自这个新的匿名函数类型,增强了功能。

React框架大量使用了Mixin技术。

六、异常

1、抛出异常

使用throw关键字抛出异常。

使用throw关键字可以抛出任意对象的异常

2、捕获

try…catch语句捕获异常

try….catch…finally ,语句捕获异常,finally保证最终一定执行。

try{

throw 1;

}catch (error){

console.log(error.constructor.name);

}finally{

console.log('end')

}

3、模块化

(1)简介

Js主要是在前端的浏览器中使用,js文件下载缓存到客户端,在浏览器中执行。

简单的表单的本地验证,漂浮广告。

服务器端使用ASP、JSP等动态网页技术,将东外生成数据嵌入一个HTML模板中,里面夹杂着js后使用<script>标签,返回给浏览器端。Js只是简单的函数和语句的组合。

2005年后,google大量使用ajax技术,可以一步请求服务器端数据,前端交互的巨大变化,

前端功能需要越来越多,代码多,js文件的增多。全局变量污染,函数名冲突,无法表达脚本之间的依赖关系,用脚本文件先后加载实现的,需要模块化的出现。

2008年v8引擎,2009年nodejs,支持服务器端JS编程,没有模块化是不可以的。

之后产生了commonjs规范,

Common规范,使用全局 require函数导入模块,使用exports导出变量。

AMD(asynchronous module
definition)异步模块定义:使用异步方式加载模块,模块的加载不影响他后面语句的执行,所有依赖此模块的语句,都需要定义在一个回调函数里面,回调函数中使用模块的变量和函数,模块加载完成后,回调函数才会执行,就可以安全的使用模块的资源,就是AMD/requires。AMD虽然是异步,但是会预先加载和执行。

CMD(common module definition),使用seajs,作者是淘宝前端玉伯,兼容并包解决了requirejs的问题。Cmd推崇as lazy as possible,尽可能的懒加载。

(2)ES6模块化

Import语句,导入另一个模块导出的绑定。

Export语句,从模块中导入函数、对象、值,供其他模块import导入引用。

(3)导出

建立模块的目录src,此目录下建立mode.js,  内容是导入和导入模块的代买

export default function a(){   //导出缺省的

console.log('a is t1')

};

a();

//导出函数

Export function foo(){

Console.log(‘foo function’);

}

//导出常量

Export const consta = ‘aaa’

(4)导入

import a from './t1-1'

a();

vs code可以很好的语法支持,但是运行环境和v8引擎,不能很好的支持模块化语法。

4、编译器

转译从一种语言代码转换到另一语言代码,当然也可以从高版本转译到低版本的支持语句。

由于js存在不同的版本,不同浏览器兼容问题,使用transpiler转译工具解决。

Babel

开发中比较新的es6的语法,通过转移器指定Wie特定的某些版本代码。

官网:http://babeljs.io/

function* inc()

{

let i = 0;

let j = 2;

while(true){

yield i++

if (!j--)return  100;

}

}

let gen = inc()

for (let i = 0 ;i<10;i++)

console.log(gen.next());

转化结果:

"use strict";

var _marked = /*#__PURE__*/regeneratorRuntime.mark(inc);

function inc() {

var i, j;

return regeneratorRuntime.wrap(function
inc$(_context) {

while (1) {

switch (_context.prev
= _context.next) {

case 0:

i = 0;

j = 2;

case 2:

if (!true) {

_context.next = 9;

break;

}

_context.next
= 5;

return i++;

case 5:

if (j--) {

_context.next = 7;

break;

}

return
_context.abrupt("return", 100);

case 7:

_context.next
= 2;

break;

case 9:

case
"end":

return _context.stop();

}

}

}, _marked, this);

}

var gen = inc();

for (var i = 0; i < 10; i++) {

console.log(gen.next());

}

缺省必须写在外头,函数和类。

5、预设

有presets,预设的一些

6、转义安装配置****

1)新建文件夹src 和lib

将导入和导出文件放入src文件中。

目录下打开shell  敲入命令npm init 生成package.json文件。

2)设置镜像

.npmrc文件

echo
"registry=https://registry.npm.taobao.org" > .npmrc

3)安装

项目根目录下。

$
npm install babel-core babel-cli 
--save-dev

安装完成后,会在项目根目录下出现node_moudles

4)修改package.json文件

"name": "trans",

"version": "1.0.0",

"description": "trans test",

"main": "index.js",

"directories": {

"lib": "lib"

},

"scripts": {

"build": "babel src -d lib"

},

"author": "",

"license": "ISC",

"devDependencies": {

"babel-cli": "^6.26.0",

"babel-core": "^6.26.3"

}

}

替换为这样的。

"build": "babel src -d
lib"   的意思是从src目录转义后输出到lib目录。

7、准备目录

项目根目录下创建src和lib目录。

Src是源码目录。

Lib是目标目录

8、配置babel和安装依赖

touch
.babelrc  创建此文件,内容如下 
.babelrc没有后缀

{

“presets”:["env"]

}

Env是当前环境自动选择。

安装依赖

npm
install babel-preset-env  -save-dev

9、准备js文件

export default function a(){

console.log('a is t1.a()')

};

export function b(){

console.log('t1.b()')

};

export 
let c = 100;

export 
var d = 200;

export const e = 300;

import a from './mod'

a();

在项目根目录下:

$
npm run build

>
trans@1.0.0 build C:\Users\WCL\Documents\trans    //

>
babel src -d lib                         
//

src\index.js
-> lib\index.js       //

src\mod.js
-> lib\mod.js           //

两个文件被转译。

运行文件:

$
node lib/index.js

a
is t1.a()

使用babel转译工具转译js非常流行。

可以提高开发效率,兼容性交给转移器处理。

lib
下的index转译后的文件格式:

'use
strict';

var
_mod = require('./mod');

var
_mod2 = _interopRequireDefault(_mod);

function
_interopRequireDefault(obj) { return obj && obj.__esModule ? obj : {
default: obj }; }

(0,
_mod2.default)();

Mod的文件;

'use
strict';

Object.defineProperty(exports,
"__esModule", {

value: true

});

exports.default
= a;

exports.b
= b;

//
function a(){

//     console.log('test')

//
}

//
export default

function
a() {

console.log('a is t1.a()');

};

function
b() {

console.log('t1.b()');

};

var
c = exports.c = 100;

var
d = exports.d = 200;

var
e = exports.e = 300;

10、导入导出

导出文件代码全部在src下的mod.js文件,导入文件都在index.js文件下

export default function a(){

console.log('a is t1')

};

//缺省导出,匿名函数

export default function(){

console.log('default export function')

}

a();

//缺省导入

import defaultFunc from './mod'

defaultFunc();

缺省导入的时候,可以自己重新命名,不需要和缺省导出 的时候一致。

缺省导入,不需要在import后使用花括号。

/**

* 导出举例

*/

//缺省导出类

export default class{

constructor(x){

this.x = x;

}

show(){

console.log(this.x)

}

}

//命名导出函数

export function foo(){

console.log('regular foo()')

}

//函数定义

function bar(){

console.log('regular bar()')

}

//变量常量定义

let x= 100;

var b = 200;

const z=300;

export {bar,x ,y,z};

/**

* 导入

*/

import defaluts,{foo,bar,x,y,z as CONST_c}from './mod'

foo();

bar();

console.log(x);

console.log(y);

console.log(CONST_c);

new defaluts(100).show();

导入所有的导出,会使用一个新的名词空间,使用名词空间可以避免冲突。

Import * as newmod from ‘./mod’;

Newmod.foo();

Newmod.bar();

New newmod.default(200).show();

七、解构

Js的参数解构参考文档;
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax

1、列表解构

var a = [1,2,3,4,5,6]

var b = [...a,7,8,9,0]

console.log(b)

[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ]

2、参数解构

//参数

function f(x,y,z){

console.log(x+y+z)

}

var args = [1,2,3,4]

f(...args);

结果为6,按照位置一一对应参数,多了的参数不用管,少的参数直接为undefined。

3、数组

解构的时候也是利用数组进行接数值。

//数组解构

const arr = [1,2,3]

let [x,y,z] = arr

console.log(x,y,z)

//丢弃元素

const [,b,] = arr

console.log(b)

//少于数组元素

const[c,d] = arr

console.log(c,d)

//多余数组元素

const[e,f,g,h] = arr

console.log(e,f,g,h)

//可变变量

const[i,...args] = arr

console.log(i)

console.log(args)    //可变的参数args收集多个,利用的数数组

//支持默认参数

const[k=20,l=34,,,p=222] = arr

console.log(k,l,p)       //没有的话默认使用默认参数,有的话优先使用数组的元素

数组,可变参数的收集就是数组。

可变参数不能给缺省值。

可以丢弃,参数可以多,可以少,少的全部使用undefined。

4、对象解构

const obj = {

a:100,

b:200,

c:300

};

//let {x,y,z} = obj;

//console.log(x,y,z) //undefined undefined undefined  名字要与之对应的。

let {a,b,c} = obj

console.log(a,b,c)    //名字是key的名字, 100,200,300

//let {a:x,b:y,c:z} = obj  //设置别名,

//console.log(a,b,c)

//console.log(x,y,z)    //利用别名打印出消息

//缺省值

let {a:x,b:y,c:z='abc'} = obj

console.log(x,y,z)

结构的时候,提供对象的属性名(key),可以根据属性名找到对应的值,
没有找到对应的值使用缺省值,没有缺省值的话就是undefined,也可以采用别名的方式,把key改成别名,通过别名进行访问属性的值。

别名:

Obj解构。

5、复杂结构

(1)嵌套的数组:

const arr = [1,[2,3],4]

const [a,[b,c],d] = arr

console.log(a,b,c,d)    //1 2 3 4

const [e,f] = arr

console.log(e,f)  //嵌套的可以接一个数组,作为外层的一个元素。

//1 [ 2, 3 ]

let [g,h,i,j=19] = arr

console.log(g,h,i,j)    //1 [ 2, 3 ] 4
19

var [k,...l] = arr

console.log(k,l)   //1 [ [ 2, 3 ],
4 ]

(2)对象

var atim = {

title:'secation',

tranliat:[

{

local:'def',

local_tart:[],

last_dict:'2222222',

url:'/def/ac/asd/ffff',

titile:'java'

}

],

url:'wwwww.xxxxxx.com'

}

// let {titile,tranliat,url} = atim

// console.log(titile,tranliat,url)

let{titile,tranliat:[{local}],url} = atim

console.log(local)

还是利用属性名(key)查询所对应的值。

6、数组的操作

方法

描述

Push(…items)

尾部增加多个元素

Pop()

移除最后一个元素,并返回

Map

引入处理函数中来处理数组中的每一个元素,返回新的数组

Filter

引入处理函数处理数组中的每一个元素,此处理函数返回true的元素保留,否则该元素被过滤掉了,保留的元素构成新的数组返回。

Foreach

迭代所有元素,无返回值

const arr = [1,2,3,4,5,6]

arr.push(6,7,8,9,0)

console.log(arr)

arr.pop()

console.log(arr)

const newarr = arr.map(x=>x*x)

console.log(newarr)

let newarr1 = arr.filter(x=>x%2==0)

console.log(newarr1)

let newarr2 = arr.forEach(x=>x+1)

console.log(newarr2)  //没有新的返回值

练习题:

s = Math.sqrt(10)

const arr = [1,2,3,4,5]

//console.log(arr.filter(x=>x%2==0 && x>3).map(x=>x*x))

//console.log(arr.filter(x=>x>s && x%2==0).map(x=>x*x))

let newarr = []

arr.forEach(x=>{

if (x>s && x%2==0) newarr.push(x*x)

})

console.log(newarr)

map返回每次都会返回一个新的值。

filter过滤解决,返回一个新的。

foreach迭代元素,没有任何返回值,返回新的结果是采用新的数组。

数据算数的问题:能过滤先过滤,先过滤在进行计算。

7、对象操作

Object静态方法

描述信息

Object.keys(obj)

Es5开始,返回所有的key

Object.values(obj)

返回所有值

Object.entries(obj)

返回所有值

Object.assign(target,…sources)

使用多个source对象,来填充target对象,返回target对象

const obj = {

a:100,

b:200,

c:300

};

console.log(Object.keys(obj));

console.log(Object.values(obj))

console.log(Object.entries(obj))  //二元数组

var atim = {

title:'secation',

tranliat:[

{

local:'def',

local_tart:[],

last_dict:'2222222',

url:'/def/ac/asd/ffff',

titile:'java'

}

],

url:'wwwww.xxxxxx.com'

}

var copy = Object.assign(

{},atim,{

name:'xxxxxx',url:'www.xxxx.com'

},{tranliat:null}

)

console.log(copy)

{ title: 'secation',

tranliat: null,

url: 'www.xxxx.com',

name: 'xxxxxx' }

属性和值的动态增加和替换等,返回新的。

八、promise

1、概念

Promise对象用于一个异步操作的最终完成(包括成功和失败,)即结果值的表示。

处理异步请求,之所以叫做promise,就是承诺,如果成功怎么处理,失败怎么处理。

语法格式:

new promise(

//executor函数

function(resolve,reject){….});

(1)executor

是一个带有resolve和reject两个参数的函数,

Executor函数在promise构造函数执行同步执行,被传递resolve和reject函数(execu函数在promise构造函数返回前被调用)

Executor内部通常会执行一些异步操作,一旦成功,可以调用resolve函数将promise状态改成fulfilled即完成,或者在发生错误的时候将其状态改为rejected失败

如果在executor函数中抛出一个错误,那么该promise状态为rejected,executo函数的返回值被忽略。

Executor中,resolve或者reject函数只能执行一个。

(2)promise状态

Pending初始状态,不是成功和失败的状态

Fulfilled意味成功

Rejected,意味着失败了。

(3)promise.then(onfulfilled,Onrejected)

参数是两个函数,根据promise的状态来调节不同的函数,fulfilled走的是onfulfiled,reject走的Onrejected。Then得返回值是一个新的promise对象,调用任何一个参数后,其返回值会被新的promise对象来resolve向后传递,

var myPromise = new Promise((resolve,reject)=>{

resolve('ok')

console.log('======')

reject('no') 
//不会执行到

})

console.log(myPromise);

myPromise.then(

(value)=>console.log(1,myPromise,value),

(reason)=>console.log(2,myPromise,reason)

)

======

Promise { 'ok' }

1 Promise { 'ok' } 'ok'

(4)catch(onrejected)

为当前promise对象添加一个拒绝回调,返回一个新的promise对象,onrejected函数调用其返回值会被新的promise对象用来resolve。

var myPromise = new Promise((resolve,reject)=>{

resolve('ok')

console.log('======')

reject('no')

})

console.log(myPromise);

//链式处理

myPromise.then(

/**

成功就会显示结果

*/

(value)=>console.log(1,myPromise,value),

/**

* 失败就显示原因

*/

(reason)=>console.log(2,myPromise,reason)

).then(

function(v){

console.log(2.5,v);

return Promise.reject(v+'++++++')

}

).catch(reason=>{

console.log(3,reason)

return Promise.resolve(reason)

})

(5)异步调用实例

function runAsync(){

return new Promise(function(resolve,reject){

setTimeout(function(){

console.log('do sth...')

resolve('ok...')

},3000);

})

}

runAsync().then(value=>{

console.log(value)

return Promise.reject(value+'*')

}).catch(reason=>{

console.log(reason)

return Promise.resolve(reason+'*')

}).then(value=>{

console.log(value)

console.log('end')

})

console.log('----fin-----')

----fin-----

do sth...

ok...

ok...*

ok...**

end

不会阻塞执行,按照顺序执行,顺序执行后按照要求进行调度处理。

严格模式:定义常量时候必须使用var这些等。

js前端技术的更多相关文章

  1. JS前端无侵入实现防止重复提交请求技术

    JS前端无侵入实现防止重复提交请求技术 最近在代码发布测试的过程中,我发现有些请求非常的消耗服务器资源,而系统测试人员因为响应太慢而不停的点击请求.我是很看不惯系统存在不顺眼的问题,做事喜欢精益求精, ...

  2. 大前端技术系列:TWA技术+TensorFlow.js => 集成原生和AI功能的app

    大前端技术系列:TWA技术+TensorFlow.js => 集成原生和AI功能的app ( 本文内容为melodyWxy原作,git地址:https://github.com/melodyWx ...

  3. 【转发】网易邮箱前端技术分享之javascript编码规范

    网易邮箱前端技术分享之javascript编码规范 发布日期:2013-11-26 10:06 来源:网易邮箱前端技术中心 作者:网易邮箱 点击:533 网易邮箱是国内最早使用ajax技术的邮箱.早在 ...

  4. HTML5学堂 全新的HTML5/前端技术分享平台

    HTML5学堂 全新的HTML5/前端技术分享平台 HTML5学堂是做什么的? HTML5学堂~http://www.h5course.com~由多名热爱H5的讲师们组成的一个组织.致力于构建一个前端 ...

  5. D2 前端技术论坛总结(上)

    得幸获得D2前端技术论坛门票一张,今天就去了,公司还给批假了(有可能不会算做请假,哈哈). 早上8点50出门,骑个小毛驴,大概9点30分左右,到了阿里巴巴西溪园区,很多人,进去的门口有专人接待,看D2 ...

  6. 百度前端技术学院(IFE)2016春季学期总结

    今天(5月16日)作为第八个提交者提交了任务五十:RIA微型问卷管理平台 这样一个综合性的大任务,宣告我的IFE春季学期课程学习顺利完成.其实任务五十并不复杂,现在再让我来做,可能一周不到就写出来了, ...

  7. Xvfb+YSlow+ShowSlow搭建前端性能测试框架 - 前端技术 | TaoBaoUED

    Xvfb+YSlow+ShowSlow搭建前端性能测试框架 - 前端技术 | TaoBaoUED Xvfb+YSlow+ShowSlow搭建前端性能测试框架 作者:黑三 | 时间:2010-07-07 ...

  8. 最受欢迎web前端技术总结

    Web前端技术发展非常快,主流技术的进步.想想刚毕业那会用asp技术.目前,该网站已经非常少见主流应用. 后来的后来J2EE框架.然后SpringMVC声望,然而,最近的各种js框架广泛传播,Html ...

  9. 前端技术之_CSS详解第一天

    前端技术之_CSS详解第一天 一html部分 略.... 二.列表 列表有3种 2.1 无序列表 无序列表,用来表示一个列表的语义,并且每个项目和每个项目之间,是不分先后的. ul就是英语unorde ...

随机推荐

  1. C# 类 (6) -继承

    继承 定义类的时候,public class Dog:Animal 表示 Dog 这个类是 继承自 Animal,冒号后面的是它的基类 继承后 的Dog 类,当调用Dog.Great() 的时候输出的 ...

  2. Ubuntu pppoeconf失败

    之前是通过sudo pppoeconf一路yes就可以连通有线网络(dsl和ethernet)的, 系统再次瘫痪后终于进入图形界面, 有线网络丢失, sudo pppoeconf也fail了, 其实加 ...

  3. GraphQL All In One

    GraphQL All In One refs https://github.com/hasura/learn-graphql xgqfrms 2012-2020 www.cnblogs.com 发布 ...

  4. Caddyfile 是干什么的?

    Caddyfile 是干什么的? The Caddyfile is a convenient Caddy configuration format for humans. It is most peo ...

  5. svn conflict & svn cleanup

    svn conflict & svn cleanup OK $ svn --help $ svn cleanup Tree Conflicts https://tortoisesvn.net/ ...

  6. 扫码登录 & 实现原理

    扫码登录 & 实现原理 二维码扫描登录是什么原理? https://time.geekbang.org/dailylesson/detail/100044032 xgqfrms 2012-20 ...

  7. React Native & CodePush & App Center

    React Native & CodePush & App Center https://docs.microsoft.com/en-us/appcenter/distribution ...

  8. js clear copy

    js clear copy window.getSelection().empty() & window.getSelection().removeAllRanges() & docu ...

  9. 【springboot读取配置文件】@ConfigurationProperties、@PropertySource和@Value

    概念: @ConfigurationProperties : 是springboot的注解,用于把主配置文件中配置属性设置到对于的Bean属性上 @PropertySource :是spring的注解 ...

  10. Spark和Spring整合处理离线数据

    如果你比较熟悉JavaWeb应用开发,那么对Spring框架一定不陌生,并且JavaWeb通常是基于SSM搭起的架构,主要用Java语言开发.但是开发Spark程序,Scala语言往往必不可少. 众所 ...