javascript知识点

九九乘法表
    var str = ''
    for(var i = 1; i <= 9; i++) {
        for(var j = 1; j <= i; j++){
            str += j + '*' i + '=' + i*j + '\t'
        }
        str += '\n'
    }
    console.log(str)
冒泡排序
    var arr = []
    var temp
    for(var i = 0; i < arr.length -1; i++){
        for(var j = 0; j < arr.length - i -1; j++){
            if (arr[j] > arr[j+1]) {
                temp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] =temp
            }
        }
    }
    console.log(arr)

预解析
js引擎会把js里面的所有var和function提升到当前作用域的最前面。
分为变量预解析(变量提升) 和 函数预解析(函数提升)
变量提升: 就是把所有的变量声明提升到当前作用域最前面,但不提升赋值操作
函数提升: 就是把所有的函数声明提升到当前作用域最前面,但不调用函数

数组的常用方法
增删改
    arr.push("hello")  //在数组的末尾添加 返回添加元素后的数组长度 影响原数组
    arr.unshift("hello")   //在数组的头部添加 返回添加元素后的数组长度 影响原数组
    arr.pop()   //在数组的末尾删除一个元素 并返回删除的元素  影响原数组
    arr.shift()   //在数组的头部删除一个元素 并返回删除的元素 影响原数组
    arr.splice(截取开始下标,截取个数,加入元素)  //影响原数组
    splice(index,count[,元素1,…,元素n])
    splice() 方法功能比较强,它可以实现删除指定数量的元素、替换指定元素以及在指定位置添加元素。这些不同功能的实现需要结合方法参数来确定:
    当参数只有 index 和 count 两个参数时,如果 count 不等于 0,splice() 方法实现删除功能,同时返回所删除的元素:从 index参数指定位置开始删除 count 参数指定个数的元素;
    当参数为 3 个以上,且 count 参数不为0时,splice() 方法实现替换功能,同时返回所替换的元素:用第三个及其之后的参数替换 index 参数指定位置开始的 count 参数指定个数的元素;
    当参数为 3 个以上,且 count 参数为 0 时,splice() 方法的实现添加功能:用第三个及其之后的参数添加到 index 参数指定位置上。
查询和拼接
    str.slice(start, end)  //截取返回从下标start开始到下标end之前的字符串,不影响原字符串
    str.substr(start, length)    //截取返回从下标start开始,指定length长度的字符串
    arr.concat(arr1)   或者   [...arr,...arr1]  //数组合并不影响原数组
    arr.join("+")   //数组转换为字符串 各元素之间用'+'连接
    str.split(',')  //字符串转换为数组
排序    
    arr.sort((a,b)=>{
        return a-b  //a-b正序   ,b-a倒序
    })
    //改变原数组而且返回原数组,默认的排序规则是按照ASCII表码值排序
    arr.reverse() //按照下标的顺序倒过来重排列元素 改变原数组返回原数组
验证是否包含某一项
    indexOf()  //返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1
    find() 用于找出第一个符合条件的数组成员,没有则返回 undefined
    findindex() 用于找出第一个符合条件的数组成员的下标,没有则返回-1
    includes() 表示某个数组是否包含给定的值,返回布尔值。
迭代
// foreach 迭代(遍历)数组
    var arr = [1, 2, 3]
    arr.forEach(function (value, index, array) {
        console.log('每个元素值' + value);
        console.log('每个元素的索引' + index);
        console.log('数组本身' + array);
    })

// filter方法创建一个新数组(返回新的数组),新数组中的元素通过检查指定数组中符合条件的元素,主要用于筛选数组
    var arr1 = [12, 56, 33, 88, 66];
    var newArr = arr1.filter(function (value, index) {
        return value > 33;
    })
    console.log(newArr);

// some方法 用于检测数组中的元素是否满足指定条件,返回值是布尔类型,查找到则返回true,反之false
    // 如果找到第一个满足条件的元素,则终止循环,不再查找
    var arr2 = [33, 44, 55];
    var flag = arr2.some(function (value) {
        return value > 50;
    })
    console.log(flag);  

map(callback)返回一个新的数组。为每个元素执行callback方法
    let arr = [1,2,3,4];
    let newArr = arr.map((item,index)=>{return item*2}); //callback要有return
    console.log(newArr);  // [2,4,6,8]

every(callback)返回Boolean 判断数组中每一个元素是否满足callback函数(只有所有的元素都满足时才返回true,只要有不满足的元素就立即终止遍历并返回false)
    let arr = [1,2,3,4]
    let res = arr.every((item,index)=>{
        console.log(item);  // 1
        return item>2
    });  
    console.log(res)  //false

Math
    Math.abs() 求绝对值
    Math.ceil(10.1) 返回大的值11
    Math.floor(10.9) 返回小的值10
    Math.random() 随机数
    Math.round() 四舍五入

节点操作
    .parentNode 得到离元素最近的父节点
    .childNodes 得到子元素的节点和文本
    .children     只得到子元素节点
    .nextSibling下一个兄弟节点
    ul.appendChild(li)添加节点到末尾
    ul.insertBefore(li, ul.children[0])添加节点到头部
    ul.removeChild(ul.children[0])删除节点
    // 克隆节点
    /* 括号为空或者里面是false 是浅拷贝 只复制标签不复制内容
    括号里面是true 是深拷贝 复制标签和内容 */
    ul.children[0].cloneNode(true);

注册事件
传统方式
    btn.onclick = function () {}
监听方式
    btn.addEventListener('click', function() {})

事件流(捕获→目标→冒泡)

事件委托也称之为事件代理(Event Delegation)。是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。

JS执行机制
一大特点就是单线程。
意味着所有任务需要排队,前一个任务结束,才会执行后一个。
导致的问题:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
为了解决这个问题,HTML5提出了Web Worker标准,允许JavaScript脚本创建多个线程。
于是,JS出现了同步和异步。

事件循环
先把同步任务放到主线程执行栈中,如果有异步任务(回调函数)就放到任务队列(消息队列)中先不执行,等同步任务做完再把异步任务(回调函数,Ajax,点击事件等)放到执行栈中执行。
主线程执行完毕,读取任务队列,取出一个任务,插入主线程处理,重复该动作。
该过程称为事件循环

构造函数
利用对象字面量创建
    var obj = {
        username: ''
        age: ''
        sayHi(): function() {}
    }
利用new object创建对象
    var obj = new Object()
    obj.username = ''
    obj.age = ''
    obj.sayHi = function() {}
自定义构造函数
    function fn(name, age) {
        this.name = name
        this.age = age
        this.sayHi = function() {}
    }

构造函数、实例、原型对象三者关系

Star的原型对象prototype    ldh的对象原型__proto__

 原型链结构

call()    apply()    bind()

严格模式
    (function () {
        'use strict';
        // 所有脚本写在这
    })();
严格模式下全局作用域中的函数中的this时undefined
如果构造函数不加new调用,this会报错

闭包(closure)指有权访问另一个函数作用域中的变量
    function fun() {
        var sum = 10;            
        function fn() {
        // 可访问fun函数中的sum 即fn为闭包函数
            console.log(sum);
        }
        return fn;
    }
    var f = fun(); // f接收的是 返回的 fn
    f(); // 所以可以f()调用
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

// 递归函数:函数内部自己调用自己,这个函数就是递归函数     
    var num = 1;
    function fn() {
        console.log('我要打印6句话。');
        if (num == 6) {
            return; // 递归中必须加退出条件 否则会栈溢出(stack overflow)
        }
        num++;
        fn();
      }
    fn();

ES6
var const let区别

箭头函数不绑定this关键字,指向的是函数定义位置的上下文this
函数体只有一句代码,且代码的执行结果就是返回值,可以省略花括号{}
    function sum(a, b) {
        return a + b;
    }
    const sum = (a, b) => a + b;
如果形参只有一个,可以省略括号()
    function fn(i) {
        return i;
    }
    const fn = v => v;

箭头函数+剩余参数
    const sum = (...args) => {
        let total = 0
        args.forEach(item => total += item)
        return total
    }
    
// startWith() 表示字符串是否在原字符串的头部 返回布尔值
    let str = 'hello world!';
    str.startsWith('hello');// true
    str.endsWith('!');// true
// repeat() 表示将源字符串重复n次 返回新字符串
    'x'.repeat(3);// 'xxx'

Symbol(未完成)

Promise实例
    const promise = new Promise((resolve, reject) => {
        // ... some code
        if (异步操作成功) {
            resolve(value);
        } else {
            reject(error);
        }
    })
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。    
    promise.then(function(value) {
        // success
    }, function(error) {
        // failure
    }

Promise.prototype.then()
Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。
then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。
    getJSON("/posts.json").then(function(json) {
          return json.post;
    }).then(function(post) {
          // ...
    });
上面的代码使用then方法,依次指定了两个回调函数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。

Promise.prototype.catch()
Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
    getJSON('/posts.json').then(function(posts) {
        // ...
    }).catch(function(error) {
        // 处理 getJSON 和 前一个回调函数运行时发生的错误
          console.log('发生错误!', error);
    })
上面代码中,getJSON()方法返回一个 Promise 对象,如果该对象状态变为resolved,则会调用then()方法指定的回调函数;如果异步操作抛出错误,状态就会变为rejected,就会调用catch()方法指定的回调函数,处理这个错误。另外,then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获。

如果 Promise 状态已经变成resolved,再抛出错误是无效的。
    const promise = new Promise(function(resolve, reject) {
          resolve('ok');
          throw new Error('test');
    });
    promise
          .then(function(value) { console.log(value) })
          .catch(function(error) { console.log(error) });
    // ok
上面代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。
未完...

Iterator(遍历器)的概念
Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。
Iterator 的遍历过程是这样的。
(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。
next方法返回一个包含value和done两个属性的对象。value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。
下面是一个模拟next方法返回值的例子。
    function makeIterator(array) {
        var nextIndex = 0
        return {
            next: function() {
                return nextIndex < array.length
                ? {value: array[nextIndex++]}
                : {done: true}
            }
        }
    }
未完...
    
Generator 函数
Generator 函数是 ES6 提供的一种异步编程解决方案
形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    var hw = helloWorldGenerator();
    hw.next() // { value: 'hello', done: false }
    hw.next() // { value: 'world', done: false }
    hw.next() // { value: 'ending', done: true }
    hw.next() // { value: undefined, done: true }

需要注意,yield表达式只能用在 Generator 函数里面,用在其他地方都会报错。
与 Iterator 接口的关系
任意一个对象的Symbol.iterator方法,等于该对象的遍历器生成函数,调用该函数会返回该对象的一个遍历器对象。
由于 Generator 函数就是遍历器生成函数,因此可以把 Generator 赋值给对象的Symbol.iterator属性,从而使得该对象具有 Iterator 接口。
next 方法的参数
yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。

Generator 函数的异步应用
    // 异步编程: 文件操作 网络操作(ajax, request) 数据库操作
    // 案例: 1s后控制台输出111 2s后输出222 3s后输出333
    // 回调地狱
    // setTimeout(() => {
    //     console.log(111);
    //     setTimeout(() => {
    //         console.log(222);
    //         setTimeout(() => {
    //             console.log(333);
    //         }, 3000);
    //     }, 2000);
    // }, 1000);

    // Generator解决回调地狱
    function one() {
        setTimeout(() => {
        console.log(111);
        iterator.next();
        }, 1000);
    }
    function two() {
        setTimeout(() => {
        console.log(222);
        iterator.next();
        }, 2000);
    }
    function three() {
        setTimeout(() => {
        console.log(333);
        iterator.next();
        }, 3000);
    }
    function * gen () {
        yield one();
        yield two();
        yield three();
    }
    let iterator = gen();
    iterator.next();

async函数
ES2017 标准引入了 async 函数,使得异步操作变得更加方便。
就是 Generator 函数的语法糖。
    const gen = function* () {
          const f1 = yield readFile('/etc/fstab');
          const f2 = yield readFile('/etc/shells');
          console.log(f1.toString());
          console.log(f2.toString());
    };
上面代码的函数gen可以写成async函数,就是下面这样。
    const asyncReadFile = async function () {
          const f1 = await readFile('/etc/fstab');
          const f2 = await readFile('/etc/shells');
          console.log(f1.toString());
          console.log(f2.toString());
    };
async函数对 Generator 函数的改进,体现在以下四点。
1)内置执行器。
async函数的执行,与普通函数一模一样,只要一行。
2)更好的语义。
async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
3)更广的适用性
co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。
4)返回值是 Promise。
async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。
进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。

返回 Promise 对象
async函数返回一个 Promise 对象。
async函数内部return语句返回的值,会成为then方法回调函数的参数。
    async function f() {
      return 'hello world';
    }
    f().then(v => console.log(v))
    // "hello world"
await 命令
正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。
    async function f() {
          // 等同于
          // return 123;
          return await 123;
    }
    f().then(v => console.log(v))
    // 123
    
Module 的语法
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
export命令
    export var firstName = 'Michael';
    export var lastName = 'Jackson';
    export var year = 1958;
export的写法,除了像上面这样,还有另外一种。
    var firstName = 'Michael';
    var lastName = 'Jackson';
    var year = 1958;
    export { firstName, lastName, year };
优先考虑使用这种写法
特别注意的是,export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。
    // 报错
    export 1;
    // 报错
    var m = 1;
    export m;
上面两种写法都会报错,因为没有提供对外的接口。
正确的写法是下面这样。
    // 写法一
    export var m = 1;
    // 写法二
    var m = 1;
    export {m};
    // 写法三
    var n = 1;
    export {n as m};

import 命令
    // main.js
    import { firstName, lastName, year } from './profile.js';
上面代码的import命令,用于加载profile.js文件,并从中输入变量。import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。

export default 命令
使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。
为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值