最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JS葵花宝典秘籍笔记,为你保驾护航金三银四

    正文概述 掘金(魔王哪吒)   2021-04-16   401

    Github来源: | 求星星 ✨ | 给个❤️关注,❤️点赞,❤️鼓励一下作者

    分享一下前端面试秘籍,希望能够帮助更多的小伙伴。加我?即可交流问题(不是大佬,互相学习,创造良好的学习环境)。以下哪些你不懂呢?

    • 首先关注公众号:微信搜:程序员哆啦A梦
    • QQ群1:711613774(已满)
    • QQ群2:634382181
    • 微信号:xiaoda0423(备注发送:已关注掘金魔王哪吒)

    一面

    一面的问题不是很难,但是要得到面试官比较高的评价,还是需要一定的表达能力和对技术比较本质的认识的,如果在回答问题的时候能够做一些适当的扩展,自然会让面试官对你有不一样的评价。

    回答问题的步骤:先回答问题本质,在回答具体细节,最后做一些平时编程中的扩展。面试官会觉得你确实是在这个技术上面下过功夫的。

    二面

    问题都比较直接,答案也是知道就知道,不知道就不知道。这些问题一部分是基础,一部分是根据你的专业技能的来提问的。

    在面试中有一些回答不出来很正常,但是如果能够做到出乎面试官的意料,也是面试官对你很重要的加分项。

    三面

    会问项目多一点,对自己做过的项目一定要深入,包括使用使用到的技术原理、为什么要使用这些技术。

    项目中某个比较重要的点是如何实现的(需要深入技术的原理),遇到的最大困难是什么(有哪些),你怎么解决的?如果需要扩展某个功能,如何降低系统的耦合度,如果针对某个功能进行优化,你会怎么设计和优化。

    四面

    主要看你的潜力(就是有没有培养的价值),但是从你平时的学习中仍然是可以看得出来的。

    五面

    诚信至上,所以在简历中不要存在任何虚假信息,企图通过虚假信息得到面试机会的后果得不偿失。对自己的是否一个明确的职业规划,表达能力、与同事相处的能力以及对工作的态度。

    arguments[]函数参数数组

    arguments[]数组只定义在函数体中。

    在函数体中,arguments指代该函数的Arguments对象。该对象拥有数值属性,可当做数组来用,含有传入到该函数的所有参数。arguments标识符本质上是一个局部变量,在每个函数中会自动声明并初始化该变量

    arguments仅在函数体中时,才指代Arguments对象,在全局代码中为undefined

    Arguments函数的参数和其他属性。

    Arguments对象只定义函数体中,从技术上来说,Arguments对象不是数组,但它拥有数值属性和length属性。

    数值类型可当做是数组元素,length属性则表示数组元素的个数,这些数组元素是传递给该方法的参数值。元素0是第一个参数,元素1是第二个参数等等。

    所有作为参数传入的值都会变成Arguments对象的数组元素,即使在函数声明中没有指定参数名。

    calleelength属性。

    1. callee属性 指代当前正在执行的函数
    2. length属性 传递给函数的参数个数,以及Arguments对象中数组元素的个数

    Arguments 对象

    arguments 是一个对应于传递给函数的参数的类数组对象。

    示例:

    function func1(a, b, c) {
      console.log(arguments[0]);
      // expected output: 1
    
      console.log(arguments[1]);
      // expected output: 2
    
      console.log(arguments[2]);
      // expected output: 3
    }
    
    func1(1, 2, 3);
    

    可以被转换为一个真正的Array:

    var args = Array.prototype.slice.call(arguments);
    var args = [].slice.call(arguments);
    
    // ES2015
    const args = Array.from(arguments);
    const args = [...arguments];
    

    Arguments对象的主要用途:

    • 用来判断有多少个参数传入函数,还可以用来指代未命名的参数
    • 除了数组元素和length属性,还可以通过callee属性来指代匿名函数本身。

    arguments.callee,指代当前正在执行的函数,通过它可以引用匿名函数自身。该属性只定义在函数体中。

    示例:

    // 在匿名函数内使用callee属性来引用匿名函数自身
    var fn = function(x) {
     if(x<2) return 1;
     else return x * arguments.callee(x-1)
    }
    var y = fn(5); // 120
    

    arguments.lengthArguments对象的length属性表示给当前函数的参数个数。该属性只能定义在函数体中。

    该属性表示的是实际传入的参数个数,不是声明的参数个数。

    示例:

    alert("实参长度:" +arguments.length);
    alert("形参长度: " +arguments.callee.length);
    
    // 使用Arguments对象来检查传入参数个数的正确性
    function check(args) {
     var actual = args.length; // 实际的参数个数
     var expected = args.callee.length; // 期待的参数个数
     if( actual != expected ) {
      throw new Error("参数个数有误,期望值:" + expected + ";实际值:" + actual);
     }
    }
    function fn(x,y,z) {
     check(arguments); // 检查参数个数的正确性
     return x+y+z;
    }
    

    Object.keys()

    Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。

    语法

    Object.keys(obj)
    

    参数

    obj

    要返回其枚举自身属性的对象。

    返回值

    一个表示给定对象的所有可枚举属性的字符串数组。

    示例:

    // simple array
    var arr = ['a', 'b', 'c'];
    console.log(Object.keys(arr)); // console: ['0', '1', '2']
    
    // array like object
    var obj = { 0: 'a', 1: 'b', 2: 'c' };
    console.log(Object.keys(obj)); // console: ['0', '1', '2']
    
    // array like object with random key ordering
    var anObj = { 100: 'a', 2: 'b', 7: 'c' };
    console.log(Object.keys(anObj)); // console: ['2', '7', '100']
    
    // getFoo is a property which isn't enumerable
    var myObj = Object.create({}, {
      getFoo: {
        value: function () { return this.foo; }
      }
    });
    myObj.foo = 1;
    console.log(Object.keys(myObj)); // console: ['foo']
    

    Object.getOwnPropertyNames()

    Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。

    语法Object.getOwnPropertyNames(obj)

    参数

    obj

    一个对象,其自身的可枚举和不可枚举属性的名称被返回。

    返回值

    在给定对象上找到的自身属性对应的字符串数组。

    示例:

    var arr = ["a", "b", "c"];
    console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
    
    // 类数组对象
    var obj = { 0: "a", 1: "b", 2: "c"};
    console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
    
    // 使用Array.forEach输出属性名和属性值
    Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
      console.log(val + " -> " + obj[val]);
    });
    // 输出
    // 0 -> a
    // 1 -> b
    // 2 -> c
    
    //不可枚举属性
    var my_obj = Object.create({}, {
      getFoo: {
        value: function() { return this.foo; },
        enumerable: false
      }
    });
    my_obj.foo = 1;
    
    console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
    

    Object.create()

    Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__

    const person = {
      isHuman: false,
      printIntroduction: function() {
        console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
      }
    };
    
    const me = Object.create(person);
    
    me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"
    me.isHuman = true; // inherited properties can be overwritten
    
    me.printIntroduction();
    // expected output: "My name is Matthew. Am I human? true"
    

    语法Object.create(proto,[propertiesObject])

    参数

    proto

    新创建对象的原型对象。

    propertiesObject

    可选。需要传入一个对象,该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。

    返回值

    一个新对象,带着指定的原型对象和属性。

    例外

    如果propertiesObject参数是 null 或非原始包装对象,则抛出一个 TypeError 异常。

    Object.create实现类式继承

    // Shape - 父类(superclass)
    function Shape() {
      this.x = 0;
      this.y = 0;
    }
    
    // 父类的方法
    Shape.prototype.move = function(x, y) {
      this.x += x;
      this.y += y;
      console.info('Shape moved.');
    };
    
    // Rectangle - 子类(subclass)
    function Rectangle() {
      Shape.call(this); // call super constructor.
    }
    
    // 子类续承父类
    Rectangle.prototype = Object.create(Shape.prototype);
    Rectangle.prototype.constructor = Rectangle;
    
    var rect = new Rectangle();
    
    console.log('Is rect an instance of Rectangle?',
      rect instanceof Rectangle); // true
    console.log('Is rect an instance of Shape?',
      rect instanceof Shape); // true
    rect.move(1, 1); // Outputs, 'Shape moved.'
    

    如果你希望能继承到多个对象,则可以使用混入的方式。

    function MyClass() {
         SuperClass.call(this);
         OtherSuperClass.call(this);
    }
    
    // 继承一个类
    MyClass.prototype = Object.create(SuperClass.prototype);
    // 混合其它
    Object.assign(MyClass.prototype, OtherSuperClass.prototype);
    // 重新指定constructor
    MyClass.prototype.constructor = MyClass;
    
    MyClass.prototype.myMethod = function() {
         // do a thing
    };
    

    Object.assign 会把 OtherSuperClass 原型上的函数拷贝到 MyClass 原型上,使 MyClass 的所有实例都可用 OtherSuperClass 的方法。

    使用 Object.create 的 propertyObject参数

    var o;
    
    // 创建一个原型为null的空对象
    o = Object.create(null);
    
    
    o = {};
    // 以字面量方式创建的空对象就相当于:
    o = Object.create(Object.prototype);
    
    
    o = Object.create(Object.prototype, {
      // foo会成为所创建对象的数据属性
      foo: {
        writable:true,
        configurable:true,
        value: "hello"
      },
      // bar会成为所创建对象的访问器属性
      bar: {
        configurable: false,
        get: function() { return 10 },
        set: function(value) {
          console.log("Setting `o.bar` to", value);
        }
      }
    });
    
    
    function Constructor(){}
    o = new Constructor();
    // 上面的一句就相当于:
    o = Object.create(Constructor.prototype);
    // 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码
    
    
    // 创建一个以另一个空对象为原型,且拥有一个属性p的对象
    o = Object.create({}, { p: { value: 42 } })
    
    // 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
    o.p = 24
    o.p
    //42
    
    o.q = 12
    for (var prop in o) {
       console.log(prop)
    }
    //"q"
    
    delete o.p
    //false
    
    //创建一个可写的,可枚举的,可配置的属性p
    o2 = Object.create({}, {
      p: {
        value: 42,
        writable: true,
        enumerable: true,
        configurable: true
      }
    });
    

    JS葵花宝典秘籍笔记,为你保驾护航金三银四

    vue准备工作

    • 学习认识flow,Vuejs源码目录设计,Vuejs源码构建,从入口开始(了解Vue准备)。
    • Flowfacebook出品的JavaScript静态类型检查工具。
    • Vue的源码利用了flow做了静态类型检查。

    flow的工作方式:

    通常类型检查分为2种:第一种:类型推断;第二种:类型注解。

    什么是类型推断呢?

    什么是类型注解呢?

    在Vuejs的主目录下有.flowconfig文件,是flow的配置文件,[libs]部分是用来描述包含指定库定义的目录。

    flow文件夹目录:

    1. compiler.js编译相关
    2. component.js组件数据结构
    3. global-api.jsglobal api结构
    4. modules.js第三方库定义
    5. options.js选项相关
    6. ssr.js服务端渲染相关
    7. vnode.js虚拟node相关

    了解Vue.js源码目录src下:

    1. compiler编译相关
    2. core核心代码
    3. platforms不同平台的支持
    4. server服务端渲染
    5. sfc-.vue文件解析
    6. shared共享代码

    Vue 初始化过程

    推荐:Vue 初始化过程

    init流程图

    JS葵花宝典秘籍笔记,为你保驾护航金三银四

    Vue的本质:其实就是一个用Function实现的Class,通过它的原型prototype以及它本身扩展的一系列的方法和属性。

    对数据渲染的过程有了更深的一层理解,从new Vue()开始,创建了一个vue是对象,会先进行init初始化——>$mount()——>compile(若已经是render则该过程不需要)——>render——>创建VNode——>patch过程——>生成真实的DOM

    如果想要任意类型T可以为null或者是undefined,只需写为?T的格式。

    var foo: string = null
    // 可以是字符串,也可以是null
    

    Vue项目中为什么要在列表组件中写key,其作用是什么

    key是给每个vnode的唯一的id,可以依靠key,更准确,更快的拿到oldVnode中对应的vnode节点。

    ['1','2','3'].map(parseInt)

    JS葵花宝典秘籍笔记,为你保驾护航金三银四

    答案是[1,NaN,NaN],为什么不是[1,2,3]呢?

    map函数的第一个参数callback,这个callback一共可以接收三个参数,其中第一个参数代表当前被处理的元素,而第二个参数代表该元素的索引。

    arr.map(callback: (value:T, index: number, array: T[]) => U, thisArg?:any);
    
    • parseInt是用来解析字符串的,使得字符串成为指定基数的整数。接收两个参数,第一个表示被处理的值(字符串),第二个表示为解析时的基数。
    parseInt(string, radix);
    

    parseINT('1', 0) 表示 radix 为0时,且string参数不以"0x"和"0"开头时,按照10为基数进行处理,返回为1。

    parseInt('2',1),基数为1,(1进制),表示的数中,最大值小于2,所以无法解析,返回为NaN。

    JS葵花宝典秘籍笔记,为你保驾护航金三银四

    什么是防抖和节流

    防抖,字面意思放置的手抖再次触发。

    onReachBottom() {
        this.timer && clearTimeout(this.timer)
        this.timer = setTimeout(this.getMoreList, 300)
    },
    

    触发高频事件后n秒后函数只会执行一次,如果n秒内高频事件再次被触发,则需要重新计算时间。

    // 掘金:魔王哪吒
    // 实现input实时搜索
    
    function debounce(fn) {
     let timeout = null
     // 创建一个标记用来存放定时器的返回值
     return function() {
      clearTimeout(timeout)
      // 每当用户输入的时候把前一个setTimeout clear掉
      timeout = setTimeout(() => {
       // 创建一个新的setTimeout,这样就能保证输入字符串后的interval间隔内如果还有字符输入的话,就不会执行fn函数
       fn.apply(this, arguments);
      },500)
     }
    }
    
    function sayHi() {
     console.log('防抖成功')
    }
    var inp = document.getElementById('inp');
    inp.addEventListener('input',debounce(sayHi)); // 防抖
    

    节流,字面节约流量,高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执 行频率。

    // 掘金:魔王哪吒
    function throttle(fn) {
     let canRun = true; // 通过闭包保持一个标记
     return function() {
      if(!canRun) return
      // 在函数开头判断标记是否为true,不为true则return
      canRun = false // 立即设置为false
      setTimeout(() => {
       fn.apply(this,argument);
       // 最后在setTimeout执行完毕后再把标记设置为true表示可以执行下一次循环了,当定时器没有执行的时候标记为false
       canRun = true
      },500)
     }
    }
    
    function sayHi(e) {
     console.log(e.target.innerWidth, e.target.innerHeight)
    }
    window.addEventListener('resize', throttle(sayHi));
    

    Set, Map, WeakSet, WeakMap

    set,对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用

    weakset,成员都是对象,成员都是弱引用,可以被垃圾回收机制回收,可以用来保存DOM节点不容易造成内存泄漏

    Map,本质上是键值对的集合,类似集合,可以遍历,方法很多,可以跟各种数据格式转换。

    WeakMap,只接收对象为键名(null除外),不接收其他类型的值作为键名,键名是弱引用,键值可以是任意的键名所指向的对象可以被垃圾回收,此时键名是无效的,不能遍历,方法有get,set,has,delete

    深度优先遍历和广度优先遍历

    深度优先遍历

    指从某个顶点出发,首先访问这个顶点,然后找出刚访问 这个结点的第一个未被访问的邻结点,然后再以此邻结点为顶点,继续找它的 下一个顶点进行访问。重复此步骤,直至所有结点都被访问完为止。

    广度优先遍历

    是从某个顶点出发,首先访问这个顶点,然后找出刚访问这个结点所有未被访问的邻结点,访问完后再访问这些结点中第一个邻结点的所有结点,重复此方法,直到所有结点都被访问完为止。

    //1.深度优先遍历的递归写法
    function deepTraveral(node) {
     let nodes = []
     if(node != null) {
      nodes.push[node]
      let childrens = node.children
      for(let i=0; i<childrens.length; i++) deepTraversal(childrens[i])
     }
     return nodes
    }
    
    //2.深度优先遍历的非递归写法
    function deepTraversal(node) {
     let nodes = []
     if(node != null) {
      let stack = []
      // 用来存放将来要访问的节点
      stack.push(node)
      while(stack.length != 0) {
       let item = stack.pop()
       // 正在访问的节点
       nodes.push(item)
       let childrens = item.children
       for(let i = childrens.length-1; i>=0; i--) stack.push(childrens[i])
       // 将现在访问点的节点的子节点存入stack,供将来访问
      }
     }
     return nodes
    }
    
    //3.广度优先遍历的递归写法
    function wideTraversal(node) {
     let nodes = [], i = 0
     if(node != null) {
      nodes.push(node)
      wideTraversal(node.nextElementSibling)
      node = nodes[i++]
      wideTraversal(node.firstElementChild)
     }
     return nodes
    }
    
    //4.广度优先遍历的非递归写法
    function wideTraversal(node) {
     let nodes = [], i=0
     while(node != null) {
      nodes.push(node)
      node = nodes[i++];
      let childrens = node.children
      for(let i=0; i<childrens.length; i++) {
       nodes.push(childrens[i])
      }
     }
     return nodes
    }
    

    实现一个拷贝函数?

    Object.prototype.toString()

    toString() 方法返回一个表示该对象的字符串。

    function Dog(name) {
      this.name = name;
    }
    
    const dog1 = new Dog('掘金魔王哪吒');
    
    Dog.prototype.toString = function dogToString() {
      return `${this.name}`;
    };
    
    console.log(dog1.toString());
    // expected output: "掘金魔王哪吒"
    

    语法

    obj.toString()
    // 返回值
    // 一个表示该对象的字符串。
    

    每个对象都有一个 toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。

    var o = new Object();
    o.toString(); // returns [object Object]
    

    可以通过 toString() 来获取每个对象的类型。为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg

    示例:

    var toString = Object.prototype.toString;
    
    toString.call(new Date); // [object Date]
    toString.call(new String); // [object String]
    toString.call(Math); // [object Math]
    
    //Since JavaScript 1.8.5
    toString.call(undefined); // [object Undefined]
    toString.call(null); // [object Null]
    

    Function.prototype.call()

    call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

    call() 方法接受的是一个参数列表

    示例:

    // 掘金:魔王哪吒
    function Product(name, price) {
      this.name = name;
      this.price = price;
    }
    
    function Food(name, price) {
      Product.call(this, name, price);
      this.category = 'food';
    }
    
    console.log(new Food('cheese', 5).name);
    // expected output: "cheese"
    

    语法

    function.call(thisArg, arg1, arg2, ...)
    

    thisArg

    可选的。在 function 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。

    arg1, arg2, ...

    指定的参数列表。

    返回值

    使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined

    描述

    call() 允许为不同的对象分配和调用属于一个对象的函数/方法。

    call() 提供新的 this 值给当前调用的函数/方法。你可以使用 call 来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。

    使用 call 方法调用父构造函数

    示例:

    // 掘金:魔王哪吒
    function Product(name, price) {
      this.name = name;
      this.price = price;
    }
    
    function Food(name, price) {
      Product.call(this, name, price);
      this.category = 'food';
    }
    
    function Toy(name, price) {
      Product.call(this, name, price);
      this.category = 'toy';
    }
    
    var cheese = new Food('feta', 5);
    var fun = new Toy('robot', 40);
    

    Function.prototype.apply()

    apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

    JS葵花宝典秘籍笔记,为你保驾护航金三银四

    语法

    // 掘金:魔王哪吒
    func.apply(thisArg, [argsArray])
    

    参数

    thisArg

    必选的。在 func 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。

    argsArray

    可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。

    返回值

    调用有指定this值和参数的函数的结果。

    描述

    在调用一个存在的函数时,你可以为其指定一个 this 对象。 this 指当前对象,也就是正在调用这个函数的对象。 使用 apply, 你可以只写一次这个方法然后在另一个对象中继承它,而不用在新对象中重复写该方法。

    用 apply 将数组各项添加到另一个数组

    // 掘金:魔王哪吒
    var array = ['a', 'b'];
    var elements = [0, 1, 2];
    array.push.apply(array, elements);
    console.info(array); // ["a", "b", 0, 1, 2]
    

    Function.prototype.bind()

    bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

    // 掘金:魔王哪吒
    const module = {
      x: 42,
      getX: function() {
        return this.x;
      }
    };
    
    const unboundGetX = module.getX;
    console.log(unboundGetX()); // The function gets invoked at the global scope
    // expected output: undefined
    
    const boundGetX = unboundGetX.bind(module);
    console.log(boundGetX());
    // expected output: 42
    

    语法

    // 掘金:魔王哪吒
    function.bind(thisArg[, arg1[, arg2[, ...]]])
    

    返回值

    返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。

    JS葵花宝典秘籍笔记,为你保驾护航金三银四

    创建绑定函数

    // 掘金:魔王哪吒
    this.x = 9;    // 在浏览器中,this 指向全局的 "window" 对象
    var module = {
      x: 81,
      getX: function() { return this.x; }
    };
    
    module.getX(); // 81
    
    var retrieveX = module.getX;
    retrieveX();
    // 返回 9 - 因为函数是在全局作用域中调用的
    
    // 创建一个新函数,把 'this' 绑定到 module 对象
    // 新手可能会将全局变量 x 与 module 的属性 x 混淆
    var boundGetX = retrieveX.bind(module);
    boundGetX(); // 81
    

    在默认情况下,使用 window.setTimeout() 时,this 关键字会指向 window (或 global)对象。当类的方法中需要 this 指向类的实例时,你可能需要显式地把 this 绑定到回调函数,就不会丢失该实例的引用。

    将一个类似于数组的对象转换成一个真正的数组

    // 掘金:魔王哪吒
    var slice = Array.prototype.slice;
    
    // ...
    
    slice.apply(arguments);
    

    Array.prototype.slice()

    slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。

    // 掘金:魔王哪吒
    const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
    
    console.log(animals.slice(2));
    // expected output: Array ["camel", "duck", "elephant"]
    
    console.log(animals.slice(2, 4));
    // expected output: Array ["camel", "duck"]
    
    console.log(animals.slice(1, 5));
    // expected output: Array ["bison", "camel", "duck", "elephant"]
    

    语法

    // 掘金:魔王哪吒
    arr.slice([begin[, end]])
    

    返回值

    一个含有被提取元素的新数组。

    描述

    slice 不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。原数组的元素会按照下述规则拷贝:

    如果该元素是个对象引用 (不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。

    对于字符串、数字及布尔值来说(不是 String、Number 或者 Boolean 对象),slice 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。

    如果向两个数组任一中添加了新元素,则另一个不会受到影响。

    类数组(Array-like)对象

    slice 方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组。你只需将该方法绑定到这个对象上。 一个函数中的 arguments 就是一个类数组对象的例子。

    // 掘金:魔王哪吒
    function list() {
      return Array.prototype.slice.call(arguments);
    }
    
    var list1 = list(1, 2, 3); // [1, 2, 3]
    

    除了使用 Array.prototype.slice.call(arguments),你也可以简单的使用 [].slice.call(arguments) 来代替。

    可以使用 bind 来简化该过程

    // 掘金:魔王哪吒
    var unboundSlice = Array.prototype.slice;
    var slice = Function.prototype.call.bind(unboundSlice);
    
    function list() {
      return slice(arguments);
    }
    
    var list1 = list(1, 2, 3); // [1, 2, 3]
    

    环状数据

    // 掘金:魔王哪吒
    const obj = {
      foo: {
        name: 'foo',
        bar: {
          name: 'bar'
          baz: {
            name: 'baz',
            aChild: null  //待会让它指向obj.foo
          }
        }
      }
    }
    obj.foo.bar.baz.aChild = obj.foo // foo->bar->baz->aChild->foo 形成环
    JSON.stringify(obj) // => TypeError: Converting circular structure to JSON
    

    拷贝这样封闭的环状数据结构,会导致死循环

    先说说什么是深拷贝与浅拷贝

    JS葵花宝典秘籍笔记,为你保驾护航金三银四

    浅拷贝:也就是拷贝A对象里面的数据,但是不拷贝A对象里面的子对象

    深拷贝:会克隆出一个对象,数据相同,但是引用地址不同(就是拷贝A对象里面的数据,而且拷贝它里面的子对象)

    浅拷贝和深拷贝的区别

    JS葵花宝典秘籍笔记,为你保驾护航金三银四

    推荐: 请分别用深度优先思想和广度优先思想实现一个拷贝函数? 每日一题系列(六)

    uniapp实现小程序微信登录

    推荐:企业微信开放平台注册流程

    推荐:uniapp实现小程序微信登录

    <button open-type="getUserInfo"/>
    

    补充:app生成签名证书

    testalias 和 test.keystore中的'test'都是可以修改的,可以替换为自己项目中的名字。输入下面的keytool -genkey命令就可以生成证书了

    keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore
    

    用签名生成工具生成签名

    JS葵花宝典秘籍笔记,为你保驾护航金三银四

    uniapp的mainfest.json文件配置中,appid必须是'_UNI_'开头,所以你的配置文件中得是'_UNI_'开头的。

    推荐:小程序静默登录方案设计

    推荐:小程序用户登录架构设计

    • Cookie + Session 登录
    • Token 登录
    • SSO 单点登录
    • OAuth 第三方登录

    SSO 单点登录,适用于中大型企业,想要统一内部所有产品的登录方式的情况。

    实现垂直居中

    // 掘金:魔王哪吒
    flex
    margin: 0 auto
    

    canvas如何实现按比例沾满全屏

    • document.documentElement.clientWidth: 可见区域宽度;
    • document.documentElement.clientHeight: 可见区域高度。
    • canvas.width = document.documentElement.clientWidth
    • canvas.height = document.documentElement.clientHeight
    • screen.availWidth:屏幕可用宽度;
    • screen.availHeight:屏幕可见高度。
    • canvas.width = screen.availWidth;
    • canvas.height = screen.availHeight;
    • screen.width:屏幕显示宽度
    • screen.height:屏幕显示高度
    • canvas.width = screen.width
    • canvas.height = screen.height
    • window.innerWidth:窗口的宽度
    • window.innerHeight:窗口的高度
    • canvas.width = window.innerWidth
    • canvas.height = window.innerHeight

    Vue2.0

    Vue源码根目录下文件夹:

    • build打包相关的配置文件,根据不同的入口,打包为不同的文件
    • dist打包之后文件所在位置
    • examples部分示例
    • flow,因Vue使用了Flow来进行静态类型检查,这里是定义了声明一些静态类型
    • packages,分别生成其他的npm
    • src,主要源码所在位置
    • compiler模板解析的相关文件
    • codegen根据ast生成render函数
    • directives通用生成render函数之前需要处理的指令
    • parser模板解析
    • core核心代码
    • components全局组件
    • global-api全局方法
    • instance实例相关内容,包括实例方法,生命周期,事件等
    • observer双向数据绑定相关文件
    • util工具方法
    • vdom虚拟dom相关
    • entries入口文件,也就是build文件夹下config.js中配置的入口文件
    • platforms平台相关的内容
    • webweb端独有文件
    • compiler编译阶段需要处理的指令和模块
    • runtime运行阶段需要处理的组件,指令和模块
    • server服务端渲染相关
    • util工具库
    • weexweex端独有文件
    • shared共享的工具方法
    • test测试用例

    从入口文件查看Vue源码

    先看package.json文件,有项目的依赖,有开发环境,生产环境等编译的启动脚本,有项目的许可信息等。来看看:npm run dev

    // 掘金:魔王哪吒
    "dev": "rollup -w -c build/config.js --environment TARGET:web-full-dev"
    

    rollup是一个类似于webpack的打包工具,入口文件:/src/entries/web-runtime-with-compiler.js

    // 掘金:魔王哪吒
    /src/entries/web-runtime-with-compiler.js   
    --> /src/entries/web-runtime.js    
    --> /src/core/index.js    
    --> /src/core/instance/index.js
    

    定义Vue对象它的构造函数及其简单:

    // 掘金:魔王哪吒
    function Vue (options) {
     // 判断是不是生产环境
      if (process.env.NODE_ENV !== 'production' &&
        !(this instanceof Vue)) {
        //如果不是通过new关键字来创建对象的话
        warn('Vue is a constructor and should be called with the `new` keyword')
      }
      this._init(options)
    }
    

    Vue的静态方法和实例方法:

    // src/core/index.js
    Vue.version = '__VERSION__'
    
    // src/entries/web-runtime-with-compiler.js
    Vue.compile = compileToFunctions    
    // 把模板template转换为render函数
    
    // src/core/global-api 
    // 在目录结构中,Vue的静态方法大多都是在该文件夹中定义的
    
    // src/core/global-api/index.js
    Vue.config 
    Vue.util 
    Vue.set
    Vue.delete
    Vue.nextTick
    Vue.options = {
      components: {KeepAlive: KeepAlive}
      directives: {},
      filters: {},
      _base: Vue
    }
    
    // src/core/global-api/use.js
    Vue.use
    
    // src/core/global-api/mixin.js
    Vue.mixin
    
    // src/core/global-api/extend.js
    Vue.extend
    
    // src/core/global-api/assets.js
    Vue.component
    Vue.directive
    Vue.filter
    
    vm._uid // 自增的id
    vm._isVue // 标示是vue对象,避免被observe
    vm._renderProxy // Proxy代理对象
    vm._self // 当前vm实例
    
    vm.$parent // 用于自定义子组件中,指向父组件的实例
    vm.$root // 指向根vm实例
    vm.$children // 当前组件的子组件实例数组
    vm.$refs 
    
    vm._watcher = null
    vm._inactive = null
    vm._directInactive = false
    vm._isMounted = false // 标识是否已挂载
    vm._isDestroyed = false // 标识是否已销毁
    vm._isBeingDestroyed = false // 标识是否正在销毁
    
    vm._events // 当前元素上绑定的自定义事件
    vm._hasHookEvent // 标示是否有hook:开头的事件
    
    vm.$vnode // 当前自定义组件在父组件中的vnode,等同于vm.$options._parentVnode
    vm._vnode // 当前组件的vnode
    vm._staticTrees // 当前组件模板内分析出的静态内容的render函数数组
    vm.$el // 当前组件对应的根元素
    
    vm.$slots // 定义在父组件中的slots,是个对象键为name,值为响应的数组
    vm.$scopedSlots = emptyObject
    // 内部render函数使用的创建vnode的方法
    vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
    // 用户自定义render方法时,传入的参数
    vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)
    
    vm._props // 被observe的存储props数据的对象
    vm._data // 被observe的存储data数据的对象
    vm._computedWatchers // 保存计算属性创建的watcher对象
    

    钩子函数:

    • beforeCreate,创建之前
    • created,创建
    • beforeMount,挂载前
    • mounted,挂载
    • beforeUpdate,更新前
    • updated,更新
    • activated,触发
    • deactivated,停用
    • beforeDestroy,销毁前
    • destroyed,毁坏
    // vm.$options
    declare type ComponentOptions = {
      // data
      data: Object | Function | void;  // 传入的data数据
      props?: { [key: string]: PropOptions }; // props传入的数据
      propsData?: ?Object;  // 对于自定义组件,父级通过`props`传过来的数据
      computed?: {  // 传入的计算属性
        [key: string]: Function | {
          get?: Function;
          set?: Function;
          cache?: boolean
        }
      };
      methods?: { [key: string]: Function }; // 传入的方法
      watch?: { [key: string]: Function | string };  // 传入的watch
    
      // DOM
      el?: string | Element;  // 传入的el字符串
      template?: string;  // 传入的模板字符串
      render: (h: () => VNode) => VNode;  // 传入的render函数
      renderError?: (h: () => VNode, err: Error) => VNode;
      staticRenderFns?: Array<() => VNode>;
    
      // 钩子函数
      beforeCreate?: Function;
      created?: Function;
      beforeMount?: Function;
      mounted?: Function;
      beforeUpdate?: Function;
      updated?: Function;
      activated?: Function;
      deactivated?: Function;
      beforeDestroy?: Function;
      destroyed?: Function;
    
      // assets
      directives?: { [key: string]: Object }; // 指令
      components?: { [key: string]: Class<Component> }; // 子组件的定义
      transitions?: { [key: string]: Object };
      filters?: { [key: string]: Function }; // 过滤器
    
      // context
      provide?: { [key: string | Symbol]: any } | () => { [key: string | Symbol]: any };
      inject?: { [key: string]: string | Symbol } | Array<string>;
    
      // component v-model customization
      model?: {
        prop?: string;
        event?: string;
      };
    
      // misc
      parent?: Component; // 父组件实例
      mixins?: Array<Object>; // mixins传入的数据
      name?: string; // 当前的组件名
      extends?: Class<Component> | Object; // extends传入的数据
      delimiters?: [string, string]; // 模板分隔符
    
      // 私有属性,均为内部创建自定义组件的对象时使用
      _isComponent?: true;  // 是否是组件
      _propKeys?: Array<string>; // props传入对象的键数组
      _parentVnode?: VNode; // 当前组件,在父组件中的VNode对象
      _parentListeners?: ?Object; // 当前组件,在父组件上绑定的事件
      _renderChildren?: ?Array<VNode>; // 父组件中定义在当前元素内的子元素的VNode数组(slot)
      _componentTag: ?string;  // 自定义标签名
      _scopeId: ?string;
      _base: Class<Component>; // Vue
      _parentElm: ?Node; // 当前自定义组件的父级dom结点
      _refElm: ?Node; // 当前元素的nextSlibing元素,即当前dom要插入到_parentElm结点下的_refElm前
    }
    

    拿到一个函数的返回值类型,使用TS

    const func = (): number => 1;
    // 声明一个泛型类型别名,返回值与泛型类型相同,入参类型不限制。
    type Reverse<T> = (arg: any) => T;
    // 声明一个泛型方法,入参arg继承泛型约束,返回空对象并断言其类型为T
    function returnResultType<T>(arg: Reverse<T>): T {
     return {} as T;
    }
    // 调用returnResultType,传入方法(arg: any) => 3,获得result返回值
    const result = returnResultType((arg:any) => 3);
    // 获取result类型并重名为ResultType
    type ResultType = typeof result;
    

    Array

    构造函数:

    new Array()
    new Array(size)
    new Array(element0, element1, ..., elementn)
    
    • size设定的数组元素个数。返回数组的length属性等于size
    • 参数列表,element0,..,elementn,当Array()构造函数用这些参数调用时,新创建的数组实例会用指定的参数值来初始化,并将length属性设置为参数个数。
    • 当不带参数调用Array()时,返回的数组为空,length属性为0。
    • concat(),把元素衔接到数组中。
    • every(),测试断言函数是否对每个数组元素都为真。
    • filter(),返回满足断言函数的数组元素。
    • forEach(),为数组的每一个元素调用指定函数。
    • indexOf(),在数组中查找匹配元素。
    • join(),将数组的所有元素转换为字符串,并衔接起来。
    • lastIndexOf(),在数组中反向查找。
    • map(),从数组的元素中,计算出新的数组元素。
    • pop(),移除数组最后一个元素。
    • push(),把元素添加到数组尾部。
    • reduce(),从数组的元素中,计算出一个值。
    • reduceRight(),从右到左缩减数组。
    • reverse(),在原数组中颠倒元素的顺序。
    • shift(),移除数组的第一个元素。
    • slice(),返回数组的一部分。
    • some(),测试是否至少有一个数组元素能让断言函数为真。
    • sort(),在原数组中对数组元素进行排序。
    • splice(),插入,删除,或替换数组元素。
    • toLocaleString(),将数组转换为本地字符串。
    • toString(),将数组转换为字符串。
    • unshift(),在数组头部插入元素。

    Array.concat()

    array.concat(value, ...)
    

    返回值,一个新数组,包含array的元素,以及衔接的新元素。

    concat()会将参数衔接到array中得到一个新数组并返回,它不会修改array,如果传给concat()的某个参数本身是一个数组,则会将该数组的元素衔接到array中,而不是数组本身。

    var a = [1,2,3];
    a.concat(4,5); // [1,2,3,4,5];
    

    Array.every()测试断言函数是否对每个元素为真

    array.every(predicate)
    array.every(predicate,o)
    

    参数:

    • predicate,用来测试数组元素的断言函数。

    • o,调用predicate时的可选this值。

    返回值:如果对array的每一个元素调用predicate时都返回真值,则返回true,如果有任何一个元素调用predicate时返回假值,则返回false

    every()方法用来测试数组的所有元素是否都满足某些条件。如果predicate的每一次调用都返回true,则every()返回true,否则,为false

    当遍历的数组为空时,every()返回true

    [1,2,3].every(function(x) { return x<5 ;}) // true
    [1,2,3].every(function(x) { return x<3 ;}) // false
    [].every(function(x) {return false;}); // true []总是返回true
    

    Array.filter()返回通过断言的数组元素

    • array.map(predicate)
    • array.map(predicate, o)
    • predicate,用来判断array中的元素是否需要包含在返回数组中的调用函数
    • o,调用predicate时的可选this

    返回值:

    一个新数组,只包含那些让predicate返回真值的数组元素

    返回新创建的数组。

    Array.forEach()为每一个数组元素调用一个函数

    array.forEach(f)
    array.forEach(f,o)
    

    参数

    f 为array的每一个元素调用的函数
    o 调用f时的可选this值
    

    返回值:该方法无返回值,注意forEach()没有返回值,特别注意,它不会返回array

    forEach(), map(), filter(), every(), some()接受函数作为第一个参数,并接受可选的第二个参数。在函数体内,this值等于o。

    如果没有指定第二个参数,this值在非严格模式下是全局对象,在严格模式下则为null

    var a = [1,2,3];
    a.forEach(function(x,i,a){ a[i]++; }); // [2,3,4]
    

    Array.indexOf()查找数组

    array.indexOf(value)
    array.indexOf(value,start)
    

    参数:

    value 要在array中查找的值
    
    start 开始查找的可选数组序号,可以省略,则为0
    

    返回值,所在index,如果不存在匹配元素时,返回-1

    判断是否相等使用的是"==="操作符
    
    ['a', 'b', 'c'].indexOf('b'); // 1
    ['a', 'b', 'c'].indexOf('d', 1); // -1
    

    Array.join(),将数组元素衔接为字符串

    array.join()
    array.join(separator)
    
    • separator,在返回的字符串中,用来分隔数组的某个元素与下一个元素的可选字符或字符串。如果省略,默认是英文逗号。

    返回值,一个字符串。

    a = new Array(1,2,3,"test");
    s = a.join("+"); // 1+2+3+test
    

    Array.lastIndexOf()反向查找数组

    array.lastIndexOf(value);
    array.lastIndexOf(value,start);
    
    • value,要在array中查找的值
    • start,开始查找的可选数组序号,如果省略,则从最后一个元素开始查找

    Array.length数组大小

    length属性表示数组中的元素个数

    Array.map()从数组元素中计算新值

    array.map(f);
    array.map(f,o);
    
    • f为array的每一个元素调用的函数,它的返回值会成为返回数组的元素。
    • o-f调用时的可选this值。

    返回值:一个新数组,由函数f计算出的元素组成。

    [1,2,3].map(function(x) { return x*x }); // [1,4,9]
    

    Array.pop()移除并返回数组的最后一个元素

    array.pop()
    

    返回值:array的最后一个元素

    pop()push(),先进后出的栈功能:

    var stack = []; // stack: []
    stack.push(1,2); // stack: [1,2] 返回2
    stack.pop(); // stack: [1] 返回2
    stack.push([4,5]); // stack: [1, [4,5]] 返回2
    stack.pop(); // stack: [1] 返回[4,5]
    stack.pop(); // stack: [] 返回1
    

    Array.push()给数组追加元素

    array.push(value,...);
    

    返回值:把指定值追加到数组后数组的新长度。(它会直接修改array,而不会创建一个新的数组)

    push()pop(),先进后出的栈功能。

    Array.reduce()从数组元素中计算一个值

    array.reduce(f);
    array.reduce(f,initial);
    
    • f一个函数,可以合并两个值,并返回一个“缩减”的新值。
    • initial,用来缩减数组的可选初始值,如果指定该参数,reduce()的行为会像把该参数插入array的头部一样。

    返回值:数组的化简值

    示例:

    [1,2,3,4].reduce(function(x,y) { return x*y; }) // 24
    

    Array.reduceRight()从右到左缩减数组

    array.reduceRight(f)
    array.reduceRight(f, initial)
    
    • f一个函数,可以合并两个值,并返回一个“缩减”的新值。
    • initial用来缩减数组的可选初始值,如果指定该参数,reduceRight()的行为会像是把该参数插入aray的尾部一样。

    返回值:数组的缩减值,该值是最后一次调用f时的返回值。

    [2,10,60].reduceRight(function(x,y) { return x/y; }) // 3
    

    Array.reverse()颠倒数组中的元素顺序

    array.reverse()
    
    a = new Array(1,2,3);
    a.reverse();
    

    Array.shift()移除数组的第一个元素

    array.shift()
    

    返回值:数组原来的第一个元素。

    var a = [1,[2,3],4];
    a.shift(); // 1
    

    Array.slice()返回数组的一部分

    array.slice(start, end)
    

    返回值:一个新数组,包含array中从start一直到end之间的所有元素(包含start指定的元素,但不包含end指定的元素),如果没有指定end,返回的数组包含从start到array尾部的所有元素。

    var a = [1,2,3,4,5];
    a.slice(0,3); // 返回 [1,2,3]
    a.slice(3); // 返回 [4,5]
    

    Array.some()测试是否有元素满足断言函数

    array.some(predicate)
    array.some(predicate,o)
    
    • predicate用来测试数组元素的断言函数
    • o调用predicate时的可选this

    返回值:如果array中有至少一个元素调用predicate时返回真值,则返回true,如果所有元素调用predicate时都返回假值,则返回false。

    [1,2,3].some(function(x) { return x>5; }); //false
    [1,2,3].some(function(x) { return x>2; }); // true
    [].some(function(x) { return false; }); // false
    

    Array.sort()对数组元素进行排序

    array.sort()
    array.sort(orderfunc)
    
    • orderfunc用来指定如何排序的可选函数

    返回值:该数组的引用。注意是在原数组中进行排序,没有新键数组。数组中的undefined元素会始终排列在数组末尾。

    function numberorder(a,b) {return a-b;}
    a = new Array(3,2,4);
    a.sort(); // 字母排序
    a.sort(numberorder); // 数值排序
    

    Array.splice()插入,删除或替换数组元素

    array.splice(start,deleteCount,value,...)
    
    • start开始插入和删除处的数组元素的序号。
    • deleteCount要删除的元素个数,从start开始,并包含start处的元素,如果指定为0,表示插入元素,而不用删除任何元素。
    • value,...要插入数组中的零个或多个值,从start序号开始插入。

    返回值:

    如果从数组中删除了元素,则返回一个新数组,包含这些删除的元素,splice()会直接修改数组。

    var a = [1,2,3,4,5,6];
    a.splice(1,2);
    

    Array.toLocaleString()将数组转换为本地字符串

    array.toLocaleString()
    

    返回值:数组的本地化字符串表示。(异常,调用该方法时,如果对象不是数组,会抛出异常。)

    Array.toString()将数组转化成字符串

    array.toString()
    

    返回值:array的字符串表示。(异常,调用该方法时,如果对象不是数组,会抛出异常。)

    Array.unshift()在数组头部插入元素

    array.unshift(value,...)
    

    参数:value,...,要插入array头部的一个或多个值。

    返回值:数组的新长度。unshift()不会创建新数组,而是直接修改数组本身。

    var a = [];
    a.unshift(1); // a:[1];
    

    Boolean对布尔值的支持

    构造函数:

    new Boolean(value) // 构造函数
    Boolean(value) // 转换函数
    

    参数:valueBoolean对象存放的值,或要转换成布尔值的值。

    • Boolean()会将参数转换成布尔值,并返回一个包含该值的Boolean对象。
    • 0,NaN,null,空字符串""和undefined都会转成false。
    • toString()根据Boolean对象代表的布尔值返回"true"或"false"字符串。
    • valueOf()返回Boolean对象中存放的原始布尔值。
    • Boolean对象时一个封装布尔值的对象。
    b.toString()
    
    • 调用该方法时,如果对象不是Boolean类型,会抛出异常.

    Date操作日期和时间

    new Date()
    new Date(milliseconds)
    new Date(datestring)
    new Date(year, month, day, hours, minutes, seconds, ms)
    

    不带参数时,Date()构造函数将根据当前日期和时间创建一个Date对象。

    返回:给定Date对象date的月份中的日期值,使用本地时间。返回值1~31之间

    decodeURI()节码一个URI中的字符

    decodeURI(uri)
    // uri
    一个包含已编码的URI或其他待解码的文本的字符串
    

    encodeURI()转义一个URI中的字符

    转义一个URI中的字符

    Function函数

    // 构造函数
    new Function(argument_names..., body)
    
    // arguments_names...
    任意多个字符串参数
    
    // body
    指定函数体的字符串
    
    // 返回
    新创建的Function对象
    
    // 异常
    SyntaxError
    表示在body参数或某个argument_names参数中存在JavaScript语法错误
    
    arguments[]
    传递给函数的参数数组,不推荐使用
    
    caller
    调用该函数的Function对象的引用,如果是全局调用,则该属性为null,不推荐使用
    

    方法:

    apply()
    将函数作为指定对象的方法来调用。传递给它的是指定的参数数组。
    
    bind()
    返回一个新函数。
    
    call()
    将函数作为指定对象的方法来调用。传递给它的是指定的参数。
    
    toString()
    返回函数的字符串表示。
    
    function.apply(调用function的对象/函数体中this/如果参数为null,则使用全局对象,一个值数组)
    // 返回
    调用函数function的返回值
    // 异常
    如果调用该函数的对象不是函数,或者参数args不是数组和Arguments对象,会抛出异常
    

    示例:

    Object.prototype.toString.apply(o);
    
    var data=[1,2,3,4,5,34];
    Math.max.apply(null,data);
    
    function.bind(o)
    function.bind(o,args...)
    // o 
    要绑定到函数上的对象
    // args...
    要绑定到函数上的零个或多个参数值
    // 返回
    一个新函数
    

    示例:

    var g = f.bind(o, 1,2);
    
    f.call(o, 1,2,3);
    
    function.call(thisobj, args...)
    
    // thisobj
    调用function的对象,在函数体中,thisobj是关键字this的值,如果这个参数为null,则使用全局对象
    // args..
    任意多个参数
    // 返回
    调用函数function的返回值
    

    示例:

    Object.prototype.toString().call(o);
    

    返回:表示函数的字符串

    Global全局对象

    全局对象不是一个类,注意,所有全局变量也都是全局对象的属性:

    • Infinity表示正无穷大的数值
    • NaN表示不是数值的值
    • undefined表示undefined
    • decodeURI()解码使用encodeURI()转义的字符串
    • decodeURIComponent()解码使用encodeURIComponent()转义的字符串
    • encodeURI()通过转义特定字符对URI编码
    • encodeURIComponent()通过转义特定字符对URI的组成部分编码
    • escape()用转义序列替换特定字符来对字符串编码
    • eval()执行JavaScript代码字符串,返回结果
    • isFinite()判断一个值是否无穷大
    • isNaN()判断一个值是否是非数值
    • parseFloat()从字符串中解析数值
    • parseInt()从字符串中解析整数
    • unescape()解码使用escape()编码的字符串
    • Array
    • Boolean
    • Date
    • Error
    • EvalError
    • Function
    • JSON
    • Math
    • Number
    • Object
    • String
    • TypeError
    • URIError

    NaN非数字属性

    NaN是一个全局属性,指向一个特殊的非数字值。NaN属性不可用for/in循环枚举,也不能用delete操作符删除。NaN不是常量,不可将它设置为任何其他值。

    Object包含所有JavaScript对象的特性的超类

    new Object()
    new Object(value)
    

    属性:constructor,引用当前对象的构造函数。

    方法:

    • hasOwnProperty()

    检查对象是否拥有一个指定名字的本地定义的属性

    • isPrototypeOf()

    检查当前对象是不是指定对象的原型

    • propertyIsEnumerable()

    检查指定名字的属性是否存在并且可以用for/in循环枚举

    • toLocaleString()

    返回该对象的一个本地化的字符串表示

    • toString()

    返回该对象的一个字符串表示

    • valueOf()

    返回当前对象的原始值,如果存在原始值的话。

    • Object.create()

    使用指定的原型及属性创建一个新的对象

    • Object.defineProperties()

    创建或配置指定对象的一个或多个属性

    • Object.defineProperty()

    创建或配置指定对象的某个属性

    • Object.freeze()

    将指定对象设置为不可改变

    • Object.getOwnPropertyDescriptor()

    查询指定对象的指定属性的特性

    • Object.getOwnPropertyNames()

    返回要给包含指定对象的所有非继承属性名的数组,包含不可枚举属性

    • Object.getPrototypeOf()

    返回指定对象的原型

    • Object.isExtensible()

    检查当前对象是否能添加到新的属性中

    • Object.isFrozen()

    检查当前对象是否已冻结

    • Object.isSealed()

    检查指定对象是否为封闭的

    • Object.keys()

    返回一个包含指定对象的所有非继承可枚举属性名的数组

    • Object.preventExtensions()

    阻止像指定对象添加新的属性

    • Object.seal()

    阻止向指定对象添加新属性或删除现有属性

    Object.constructor对象的构造函数

    所有对象的constructor属性都指向用做当前对象的构造函数的那个函数。如果使用Array()构造函数创建一个数组a,则a.constructor是一个Array

    a = new Array(1,2,3); //创建一个对象
    a.constructor == Array // 值为true
    

    检测是否是一个数组:

    function isArray(x) {
     return ((typeof x == "object") && (x.constructor == Array));
    }
    

    constructor属性经常用于检测未知对象的类型。给定一个未知的值,可以使用typeof操作符来检查它是一个原始值还是一个对象。

    如果它是一个对象,则可以使用constructor属性来检查对象的类型。

    Object.create()使用指定的原型和属性来创建一个对象

    Object.create(proto)
    Object.create(proto,descriptors)
    

    参数:

    // proto
    新创建对象的原型,可为null
    // descriptors
    一个可选对象,把属性名映射到属性描述符
    // 返回
    一个新创建的对象,继承自proto,同时拥有descriptiors所描述的属性
    

    示例:

    // 创建一个对象,有x,y属性,同时继承属性z
    var p = Object.create({z:0},{
     x: {value:1,writable: false, enumerable: true, configurable: true},
     y: {value:2,writable: false, enumerable: true, configurable: true},
    });
    

    创建或配置对象的多个属性

    // o
    要在其上创建或配置属性的对象
    // descriptors
    将属性名映射到属性描述符的对象
    // 返回
    对象o
    

    示例:

    // 把只读属性x和y添加到新创建的对象中
    var p = Object.defineProperties({},{
     x: {value:1,writable: false, enumerable: true, configurable: true},
     y: {value:2,writable: false, enumerable: true, configurable: true},
    });
    

    创建或配置对象的一个属性

    Object.defineProperty(o, name, desc)
    

    参数:

    // o
    将在其上创建或配置属性的对象
    // name
    将创建或配置的属性的名字
    // desc
    一个属性描述符对象,描述要创建的新属性或现有属性的修改
    // 返回
    对象o
    

    示例:

    function constant(o, n, v) {
     // 定义一个值为v的常量o.n
     Object.defineProperty(o, n, {value: v, writable: false, enumerable: true, configurable: false});
    }
    

    将一个对象设置为不可改变,冻结对象是一个永久性的操作,一旦冻结,就不能解冻。Object.freeze()只设置数据属性的可写特性,那些有对应setter函数的属性不会受到影响,Object.freeze()不会影响继承属性。

    查询一个属性的特性

    Object.getOwnPropertyDescriptor(o,name)
    

    参数:

    // o 
    待查询其属性特性的对象
    // name
    待查询的属性名
    // 返回
    指定对象指定属性的一个属性描述符对象,如果不存在指定属性则返回undefined
    // 描述
    属性描述符是一个对象,描述该属性的特性和值
    

    数据属性有一个值以及三个性质:

    1. 可枚举型
    2. 可读写型
    3. 可配置性

    访问器属性有一个getter和setter方法,以及可枚举性和可配置性。

    数据属性的描述符:

    {
     value:
     writable:
     enumerable:
     configurable:
    }
    

    访问器属性的描述符:

    {
     get:
     set:
     enumerable:
     configurable:
    }
    

    返回非继承属性的名字

    Object.getOwnPropertyNames(o);
    // o 一个对象
    

    返回,一个包含o的多有非继承属性的名字的数组,包含那些不可枚举的属性

    Object.getOwnPropertyNames([]) // ["length"]: "length" 不可枚举
    

    返回一个对象的原型

    var p = {}, // 一个原始对象
    Object.getPrototypeOf(p); // Object.prototype
    var o = Object.create(p); // 一个继承p的对象
    Object.getPrototypeOf(o); // p
    

    检查一个属性是否是继承的

    示例:

    var o = new Object(); // 创建一个对象
    o.x = 3.14; // 定义一个非继承的本地属性
    o.hasOwnProperty("x"); //返回true,x是o的本地属性
    o.hasOwnProperty("y"); // false , o没有属性y
    o.hasOwnProperty("toString"); //返回false,该属性是继承属性
    

    判断某个对象上是否可以添加新属性

    示例:

    var o = {}; // 新创建一个对象
    Object.isExtensible(o); // true,它是可扩展的
    Object.preventExtensions(o); // 将它设置为不可扩展的
    Object.isExtensible(o); // false
    
    • 如果一个对象的所有非继承属性都是只读的,或者它是封闭的,表示它是冻结的
    • 如果可以向一个对象添加新的属性,并且不可删除现有的属性,则称它为封闭的
    • Object.isFrozen()检测它的参数是否为冻结状态
    • 对象一旦冻结就不能再解冻了
    • 如果object是o的原型则返回true,如果o不是一个对象,或object不是o的原型则返回false。
    var o = new Object();
    Object.prototype.isPrototypeOf(o); // true: o是一个对象
    Function.prototype.isPrototypeOf(o.toString); // true,toString是一个函数
    Array.prototype.isPrototypeOf([1,2,3]); // true
    o.constructor == Object // true
    
    • 对象一旦封闭,将没有办法解封
    • 封闭一个对象:Object.seal()或Object.freeze()
    Object.keys({x:1,y:2}); // ["x","y"]
    

    禁止在一个对象上添加新的属性

    • Object.preventExtensions()将o的可扩展性设置为false,之后将不能向它添加新的属性
    • 这是一个永久性的改变

    检测某个属性是否在for/in循环中可见

    var o = new Object();
    o.x=12;
    o.propertyIsEnumerable("x"); // true
    o.propertyIsEnumerable("y"); // false
    o.propertyIsEnumerable("toString"); // false
    

    方法:

    • charAt()

    取出一个字符串中指定位置的字符

    • charCodeAt()

    返回一个字符串中指定位置的字符的编码

    • concat()

    将一个或多个值连接成一个字符串

    • indexOf()

    在指定字符串中寻找一个字符或字串

    • lastIndexOf()

    在指定字符串中向后寻找一个字符或字串

    • localCompare()

    使用本地定义的顺序比较字符串

    • replace()

    使用正则表达式执行查找与替换操作

    • search()

    在一个字符串中查找匹配某个正则表达式的字串

    • slice()

    返回字符串的一个切片或子串

    • split()

    在指定的分隔符字符串或正则表达式处断开,将一个字符串分隔为由字符串组成的数组

    • substr()

    提取字符串的一个字串,subString()的一个变体

    • substring()

    提取字符串的一个字串

    • toString()

    返回原始的字符串值

    • valueOf()

    返回原始的字符串值

    回看笔者往期高赞文章,也许能收获更多喔!

    • TypeScript趁早学习提高职场竞争力
    • 一个合格的初级前端工程师需要掌握的模块笔记
    • 前端模拟面试字数过23477万内容
    • Vue.js笔试题解决业务中常见问题
    • 【初级】个人分享Vue前端开发教程笔记
    • 长篇总结之JavaScript,巩固前端基础
    • 前端面试必备ES6全方位总结
    • 达达前端个人web分享92道JavaScript面试题附加回答
    • 【图文并茂,点赞收藏哦!】重学巩固你的Vuejs知识体系
    • 【思维导图】前端开发-巩固你的JavaScript知识体系
    • 14期-连肝7个晚上,总结了计算机网络的知识点!(共66条)
    • 这是我的第一次JavaScript初级技巧
    • localStorage和sessionStorage本地存储
    • HTML5中的拖放功能
    • 挑战前端知识点HTTP/ECMAScript
    • 必学必会-音频和视频
    • 前端170面试题+答案学习整理(良心制作)
    • 前端HTML5面试官和应试者一问一答
    • 哪吒闹海,席卷图文学习前端Flex布局
    • 腾讯位置服务开发应用
    • 【进阶】面试官问我Chrome浏览器的渲染原理(6000字长文)
    • 面试官一上来就问我Chrome底层原理和HTTP协议(万字长文)
    • 熬夜总结了 “HTML5画布” 的知识点
    • this/call/apply/bind(万字长文)
    • HTTP/HTTPS/HTTP2/DNS/TCP/经典题
    • 执行上下文/作用域链/闭包/一等公民
    • Web页面制作基础
    • 学习总结之HTML5剑指前端(建议收藏,图文并茂)

    ❤️关注+点赞+收藏+评论+转发❤️

    点赞、收藏和评论

    我是Jeskson(达达前端),感谢各位人才的:点赞、收藏和评论,我们下期见!(如本文内容有地方讲解有误,欢迎指出☞谢谢,一起学习了)

    我们下期见!


    起源地下载网 » JS葵花宝典秘籍笔记,为你保驾护航金三银四

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元