zoukankan      html  css  js  c++  java
  • js前端技术

    一、前端技术

    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、转义字符

    名称

    说明

    Null字节

    

    退格符

    f

    换页符

    换行符

    回车符

    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转义字符uD87EuDc04的简写。

    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 = ' mg edu '

    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:UsersWCLDocuments rans    //

    > babel src -d lib                          //

     

    srcindex.js -> libindex.js       //

    srcmod.js -> libmod.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这些等。

  • 相关阅读:
    CSS初识
    HTML 初识
    索引
    表查询前之数据导入
    mysql练习2
    AMP+EPP3.0的开发环境配置
    C++异步编程资料汇集贴
    Windows8中如何打包和安装一个本地的Metro类型应用(转)
    std::string, std::wstring, wchar_t*, Platform::String^ 之间的相互转换
    windows RT开发笔记:WinRT DLL及其调用研究
  • 原文地址:https://www.cnblogs.com/wangchunli-blogs/p/9949944.html
Copyright © 2011-2022 走看看