最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 已阅冴羽大佬文章 | 创作者训练营第二期

    正文概述 掘金(魔王哪吒)   2021-05-04   515

    顺便宣传一下:Github来源: | 求星星 ✨ | 欢迎 star,鼓励一下作者。

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

    • 哪里不懂的,我们可以下方评论交流

    已阅冴羽大佬文章 | 创作者训练营第二期

    已阅冴羽大佬文章 | 创作者训练营第二期

    扩展的对象功能

    已阅冴羽大佬文章 | 创作者训练营第二期

    • 对象类别

    已阅冴羽大佬文章 | 创作者训练营第二期

    命名一个函数为 createPerson() ,其作用创建了一个对象:

    function createPerson(name, age) {
     return {
      name: name,
      age: age
     };
    }
    

    当对象的一个属性名称与本地变量名相同时,ES6:

    function createPerson(name, age) {
     return {
      name,
      age
     },
    }
    

    es5写法:

    var person = {
     name: 'jeskson',
     sayName: function() {
      console.log(this.name);
     }
    };
    

    es6写法:

    var person = {
     name: 'jeskson',
     sayName() {
      console.log(this.name);
     }
    };
    
    • 需计算的属性名

    示例:

    var person = {},
        lastName = "last name";
    person["first name"] = "da1";
    person[lastName] = "da2";
    console.log(person["first name"]); // da1
    console.log(person[lastName]); // da2
    

    示例中两个属性名包含了空格,不能使用小数点表示法来引用它们,方括号表示法允许将任意字符串用作属性名。

    示例优化:

    var person = {
     "first name": "jeskson"
    };
    console.log(person["first name"]); // jeskson
    
    var lastName = "last name";
    var person = {
     "first name": "da1",
     [lastName]: "da2"
    };
    console.log(person["first name"]); // "da1"
    console.log(person[lastName]); // "da2"
    

    示例:

    var da = " name";
    var pserson = {
     ["first + da ]: "da1",
     ["last" + da ]: "da2"
    };
    console.log(person["first name"]); // "da1"
    console.log(person["last name"]); // "da2"
    
    • 相等运算符( == )或严格相等运算符( === )
    • ES6: Object.is(),返回true,要求二者类型相同并且值也相等

    示例:

    console.log(+0 == -0); // true
    console.log(+0 === -0); // true
    console.log(Object.is(+0, -0)); // false
    
    console.log(NaN == NaN); // false
    console.log(NaN === NaN); // false
    console.log(Object.is(NaN, NaN)); // true
    
    console.log(5 == 5); // true
    console.log(5 == "5"); // true
    console.log(5 === 5); // true
    console.log(5 === "5"); // false
    console.log(Object.is(5, 5)); // true
    console.log(Object.is(5, "5")); // false
    

    已阅冴羽大佬文章 | 创作者训练营第二期

    • Object.assign()方法

    浅复制,当属性值为对象时,仅复制其引用

    function mixin(receiver, supplier) {
     Object.keys(supplier).forEach(function(key) {
      receiver[key] = supplier[key];
     });
     return receiver;
    }
    

    Object.assign()方法,该方法 接受一个接收者,以及任意数量的供应者,并会返回接收者。

    示例:

    "use strict";
    var person = { 
        name: "da1",
        name: "da2" // 在 ES6 严格模式中不会出错
    };
    console.log(person.name); // "da2"
    

    已阅冴羽大佬文章 | 创作者训练营第二期

    1. Object.getPrototypeOf()方法来从任意指定对象中获取其原型
    2. Object.setPrototypeOf()方法修改任意指定对象的原型

    示例:

    let person = {
     getGreeting() {
      return "hello";
     }
    };
    let dog = {
     getGreeting() {
      return "hai";
     }
    };
    
    let friend = Object.create(person);
    console.log(friend.getGreeting()); // "hello"
    console.log(Object.getPrototypeOf(friend) === person); // true
    
    Object.setPrototypeOf(friend, dog);
    console.log(friend.getGreeting()); // "hai"
    console.log(Object.getPrototypeOf(friend) === dog); // true
    
    • Object.getPrototypeOf()方法确保了能调用正确的原型,并在其返回结果上附加了一个字符串。

    示例:

    let person = {
     getGreeting() {
      return "hello"
     }
    };
    let dog = {
     getGreeting() {
      return "woof";
     }
    };
    let friend = {
     getGreeting() {
      return Object.getPrototypeOf(this).getGreeting.call(this) + ", hi!";
     }
    };
    Object.setPrototypeOf(friend, person);
    console.log(friend.getGreeting()); // "hello hi!"
    console.log(Object.getPrototypeOf(frined) === person); // true
    Object.setPrototypeOf(friend,dog);
    console.log(friend,getGreeting()); // "woof, hi!"
    console.log(Object.getPrototypeOf(friend) === dog); // true
    
    • call(this),能确保正确设置原型方法内部的this

    示例:

    let friend = {
     getGreeting() {
      // Object.getPrototypeOf(this).getGreeting.call(this)
      return super.getGreeting() + ", hi!";
     }
    }
    

    使用ES6的super,示例:

    let person = {
     getGreeting() {
      return "hello";
     }
    };
    let friend = {
     getGreeting() {
      return super.getGreeting() + ", hi!";
    };
    Object.setPrototypeOf(friend, person);
    let relative = Object.create(friend);
    console.log(person.getGreeting()); // "hello"
    console.log(friend.getGreeting()); // "hello, hi!"
    console.log(relative.getGreeting()); // "hello, hi!"
    

    深入系列专题

    1.JavaScript 深入之从原型到原型链

    • JavaScript 深入之从原型到原型链

    2.JavaScript 深入之词法作用域和动态作用域

    • JavaScript 深入之词法作用域和动态作用域

    3.JavaScript深入之执行上下文栈

    • JavaScript深入之执行上下文栈

    4.JavaScript深入之变量对象

    • JavaScript深入之变量对象

    5.JavaScript深入之作用域链

    • JavaScript深入之作用域链

    6.JavaScript 深入之从 ECMAScript 规范解读 this

    • JavaScript 深入之从 ECMAScript 规范解读 this

    7.JavaScript深入之执行上下文

    • JavaScript深入之执行上下文

    8.JavaScript深入之闭包

    • JavaScript深入之闭包

    9.JavaScript深入之参数按值传递

    • JavaScript深入之参数按值传递

    10.JavaScript深入之call和apply的模拟实现

    • JavaScript深入之call和apply的模拟实现

    11.JavaScript深入之bind的模拟实现

    • JavaScript深入之bind的模拟实现

    12.JavaScript深入之new的模拟实现

    • JavaScript深入之new的模拟实现

    13.JavaScript 深入之类数组对象与 arguments

    • JavaScript 深入之类数组对象与 arguments

    14.JavaScript深入之创建对象的多种方式以及优缺点

    • JavaScript深入之创建对象的多种方式以及优缺点
    • ES6 class语法
    • 三要素
    • UML类图
    • 初始化npm环境
    • 安装webpack
    • 安装webpack-dev-server
    • 安装babel
    • npm init
    • package.json
    // package.json
    // "dev": "wepack --config ./webpack.dev.config.js --mode development"
    {
     "name": "design-pattern-text",
     "version": "1.0.0",
     "description": "",
     "main": "index.js",
     "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "dev": "webpack-dev-server --config ./webpack.dev.config.js --mode development"
     },
     "author": "",
     "license": "ISC",
     "devDependencies": {
     "html-webpack-plugin": "",
      "webpack": "",
      "webpack-cli": "",
      "webpack-dev-server": ""
     }
    }
    
    • npm install webpack webpack-cli --save-dev
    • webpack.dev.config.js
    // webpack.dev.config.js
    module.exports = {
     entry: './src/index.js‘, 
     output: {
      path: __dirname,
      filename: './release/bundle.js'  
     }
    }
    
    • npm run dev
    • npm install webpack-dev-server html-webpack-plugin --save-dev
    // webpack.dev.config.js
    const path = require('path')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
     entry: './src/index.js‘, 
     output: {
      path: __dirname,
      filename: './release/bundle.js'  
     },
     
     module: {
      rules: [{
          test: /\.js?$/,
          exclude: /(node_modules)/,
          loader: 'babel-loader' // es6语法转es5语法
      }]
     },
     
     glugins: [
      new HtmlWebpackPlugin({
       template: './index.html'
      })
     ],
     devServer: {
      contentBase: path.jon(__dirname,'./release'), // 根目录
      open: true, // 自动打开浏览器
      port: 8080 // 端口
     }
    }
    
    • npm install babel-core babel-loader babel-polyfill babel-preset-es2015 babel-preset-latest --save-dev
    // 根目录.babelrc
    {
     "presets": ["es2015", "latest"],
     "plugins": []
    }
    
    1. 概念
    2. 三要素:继承,封装,多态
    3. JS的应用举例
    4. 面向对象的意义

    示例:

    // 类
    class People {
     constructor(name,age) {
      this.name = name
      this.age = age
     }
     eat() {
      alert(`${this.name} eat something`)
     }
     speak() {
      alert(`My name is ${this.name}, age ${this.age}`)
     }
    }
    
    // 对象(实例)
    // 创建实例
    let da1 = new Perople('jeskson1', 12)
    da1.eat()
    da1.speak()
    
    // 创建实例
    let da2 = new People('jeskson2', 13)
    da2.eat()
    da2.speak()
    
    1. 继承,子类继承父类
    2. 封装,数据的权限和保密
    3. 多态,同一接口不同实现
    // 继承
    class People {
     constructor(name,age) {
      this.name = name
      this.age = age
     }
     eat() {
      alert(`${this.name} eat something`)
     }
     speak() {
      alert(`My name is ${this.name}, age ${this.age}`)
     }
    }
    
    // 子类继承父类
    class Student extends People {
     constructor(name, age, number) {
      super(name, age)
      this.number = number
     }
     study() {
      alert(`${this.name} study`)
     }
    }
    
    // 实例
    let jeskson1 = new Student('da1', 10, '01')
    jeskson1.study()
    console.log(jeskson1.number)
    jeskson1.eat()
    
    • 封装(public完全开发,protected对子类开放,private对自己开放)
    • 使用typescript
    // 封装 父类
    class People {
     public name
     private age
     protected weight
     constructor(name, age) {
      this.name = name
      this.age = age
      this.weight = 223
     }
     eat() {
      alert(`${this.name} eat something`)
     }
     speak() {
      alert(`My name is ${this.name}, age ${this.age}`)
     }
    }
    
    // 子类
    class Student extends People {
     number
     private grilfriend
     constructor(name, age, number) {
      super(name,age)
      this.number = number
      this.girlfriend = '小舞'
     }
     study() {}
     getWeight() {}
    }
    
    • 多态:同一接口的不同表现
    // 保持子类的开放性和灵活性
    class People {
     constructor(name) {
      this.name = name
     }
     say() {}
    }
    
    class A extends People {
     constructor(name) {
      super(name)
     }
     say() {console.log('A dadaqianduan.cn')}
    }
    
    class B extends People {
     constructor(name) {
      super(name)
     }
     say() {console.log('B dadaqianduan.cn')}
    }
    
    let a = new A('a')
    a.say()
    
    let b = new b('b')
    b.say()
    
    • 面向对象:顺序,判断,循环,结构化

    已阅冴羽大佬文章 | 创作者训练营第二期

    已阅冴羽大佬文章 | 创作者训练营第二期

    15.JavaScript深入之继承的多种方式和优缺点

    • JavaScript深入之继承的多种方式和优缺点

    JavaScript专题

    1.JavaScript专题之跟着underscore学防抖

    • JavaScript专题之跟着underscore学防抖
    1. window 的 resize、scroll
    2. mousedown、mousemove
    3. keyup、keydown

    2.JavaScript专题之跟着 underscore 学节流

    • JavaScript专题之跟着 underscore 学节流

    3.JavaScript专题之数组去重

    • JavaScript专题之数组去重

    4.JavaScript专题之类型判断(上)

    • JavaScript专题之类型判断(上)

    5.JavaScript专题之类型判断(下)

    • JavaScript专题之类型判断(下)
    Undefined、Null、Boolean、Number、String、Object
    

    已阅冴羽大佬文章 | 创作者训练营第二期

    [object Number]
    [object String]
    [object Boolean]
    [object Undefined]
    [object Null]
    [object Object]
    [object Array]
    [object Date]
    [object Error]
    [object RegExp]
    [object Function]
    [object Math]
    [object JSON]
    [object Arguments]
    
    // jquery:
    type: function(obj) {
     if(obj == null) {
      return obj + "";
     }
     
     return typeof obj === "object" || typeof obj === "function" ? class2type[toString.call(obj) ] || "object" : typeof obj;
    }
    

    6.JavaScript专题之深浅拷贝

    • JavaScript专题之深浅拷贝

    • 浅拷贝:复制引用方法,两者都会发生变化

    • 深拷贝:即使嵌套了对象,也相互分离,互不影响

    var myObj = {...};
    
    var myObj = new Object();
    

    类型:对象是JavaScript的基础。6种主要类型:

    1. string
    2. number
    3. boolean
    4. null
    5. undefined
    6. object

    函数就是对象的一个子类型,JavaScript中的函数是“一等公民”,因为它们本质上和普通的对象一样,所以可以像操作其他对象一样操作函数。

    常见内置对象:

    1. String
    2. Number
    3. Boolean
    4. Object
    5. Function
    6. Array
    7. Date
    8. RegExp
    9. Error

    Object.assign(...)方法的第一个参数是目标对象,之后还可以跟一个或多个源对象。它会遍历一个或多个源对象的所有可枚举的自有键并把它们复制到目标对象,最后返回目标对象

    示例:

    function anotherFunction() { /*..*/ }
    var anotherObject = {
     c: true
    };
    var anotherArray = [];
    var myObject = {
     a: 2, 
     b: anotherObject, // 引用,不是复本!
     c: anotherArray, // 另一个引用!
     d: anotherFunction
    };
    anotherArray.push( anotherObject, myObject );
    
    var newObj = Object.assign( {}, myObject );
    newObj.a; // 2
    newObj.b === anotherObject; // true
    newObj.c === anotherArray; // true
    newObj.d === anotherFunction; // true
    
    var myObject = {
     a: 2
    };
    Object.getOwnPropertyDescriptor(myObject, "a");
    // {
    //  value: 2,
    //  writable: true,
    //  enumerable: true,
    //  configurable: true,
    // }
    // writable可写
    // enumerable可枚举
    // configurable可配置
    
    var myObject = {};
    Object.defineProperty(myObject, "a", {
     value: 2,
     writable: true,
     configurable: true,
     enumerable: true
    });
    myObject.a; // 2
    

    使用defineProperty(...)myObject添加了一个普通的属性并显式指定了一些特性。

    • writable决定是否可以修改属性的值

    示例:

    var myObject = {};
    
    Object.defineProperty(myObject,"a",{
     value: 2,
     writable: false, // 不可写
     configurable: true,
     enumerable: true
    });
    
    myObject.a = 3;
    myObject.a; // 2
    
    • configurable,只要属性是可配置的,就可以使用defineProperty(...)方法来修改属性描述符。
    var myObject = {
     a: 2
    };
    myObject.a = 3;
    myObject.a; // 3
    
    Object.defineProperty(myObject, "a", {
     value: 4,
     writable: true,
     configurable: false, // 不可配置
     enumerable: true
    });
    
    myObject.a; // 4
    myObject.a = 5;
    myObject.a; //5
    
    Object.defineProperty(myObject, "a", {
     value: 6,
     wirtable: true,
     configurable: true,
     enumerable: true
    }); // TypeError
    
    • enumerable,控制的是属性是否会出现在对象的属性枚举中。
    // 创建一个真正的常量属性,不可修改,重定义,删除
    var myObject = {};
    Object.defineProperty(myObject, "a", {
     value: 1,
     writable: false,
     configurable: false
    });
    
    // 禁止扩展,使用Object.preventExtensions(...)
    // 禁 止 一 个 对 象 添 加 新 属 性 并 且 保 留 已 有 属 性
    var myObject = {
     a: 2
    };
    Object.preventExtensions(myObject);
    myObject.b = 3;
    myObject.b; // undefined
    
    • 密封:Object.seal(...)会创建一个“密封”的对象,这个方法实际上会在一个现有对象上调用Object.preventExtensions(...)并把所有现有属性标记为configurable:false(虽然可以 修改属性的值)。

    • 冻结:Object.freeze(..) 会创建一个冻结对象,这个方法实际上会在一个现有对象上调用 Object.seal(..) 并把所有“数据访问”属性标记为 writable:false,这样就无法修改它们的值。

    • getter是一个隐藏函数,会在获取属性值时调用
    • setter是一个隐藏 函数,会在设置属性值时调用

    示例:

    var myObject = {
     a: 2
    };
    ("a" in myObject); // true
    ("b" in myObject); // false
    myObject.hasOwnProperty("a"); // true
    myObject.hasOwnProperty("b"); // false
    
    • in操作符会检查属性是否在对象及其[[Prototype]]原型链中
    • hasOwnProperty(...)只会检查属性是否在myObject对象中,不会检查[[Prototype]]

    示例:

    var myObject = {};
    Object.defineProperty(
     myObject,
     "a",
     { enumerable: true, value: 2 }
    );
    Object.defineProperty(
     myObject,
     "b",
     { enumerable: false, value: 3}
    );
    
    myObject.b; // 3
    ("b" in myObject); // true
    myObject.hasOwnProperty("b"); // true
    
    for(var k in myObject) {
     console.log(k, myObject[k]);
    }
    // "a" 2
    

    检查属性是否可枚举:

    var myObject = {};
    Object.defineProperty(
     myObject,
     "a",
     {enumerable: true, value: 2}
    );
    Object.defineProperty(
     myObject,
     "b",
     {enumerable: false, value:3}
    );
    
    myObject.propertyIsEnumerable("a"); // true
    myObject.propertyIsEnumerable("b"); // false
    Object.keys(myObject); // ["a"]
    Object.getOwnPeropertyNames(myObject); // ["a", "b"]
    
    • propertyIsEnumerable(...)会检查给定的属性名是否直接存在于对象中,并满足enumerable: true

    • Object.keys(...)会返回一个数组,包含所有可枚举属性

    • Object.getOwnPropertyNames(...)会返回一个数组,包含所有属性,无论它们是否可枚举

    • inhasOwnProperty(...)的区别在于是否查找[[Prototype]]

    • Object.keys(...)Object.getOwnPropertyNames(...)都只会查找对象直接包含的属性

    可以使用 Object.preventExtensions(..)、Object.seal(..) 和 Object.freeze(..) 来设置对象的不可变性级别。

    ES6方法:forEach(),every(),some()

    • forEach(...)会遍历数组中的所有值并忽略回调函数的返回值
    • every(...)会一直运行直到回调函数返回false
    • some(...)会一直运行直到回调函数返回true

    ES6中新增加了一种用来遍历数组的for...of循环语法:

    示例:

    var myArray = [1,2,3];
    for(var v of myArray) {
     console.log(v);
    }
    // 1
    // 2
    // 3
    

    7.JavaScript 专题之从零实现 jQuery 的 extend

    • JavaScript 专题之从零实现 jQuery 的 extend

    8.JavaScript 专题之如何求数组的最大值和最小值

    • JavaScript 专题之如何求数组的最大值和最小值

    已阅冴羽大佬文章 | 创作者训练营第二期

    var arr = [ 2,34,5,8];
    function max(prev, next) {
     return Math.max(prev, next);
    }
    console.log(arr.reduce(max));
    
    arr.sort(function(a,b){return a-b;});
    console.log(arr[arr.length-1]);
    
    var max = eval("Math.max(" + arr + ")");
    
    Math.max.applly(null, arr);
    
    Math.max(...arr);
    

    9.JavaScript 专题之数组扁平化

    • JavaScript 专题之数组扁平化

    已阅冴羽大佬文章 | 创作者训练营第二期

    10.JavaScript专题之学underscore在数组中查找指定元素

    • JavaScript专题之学underscore在数组中查找指定元素

    11.JavaScript专题之jQuery通用遍历方法each的实现

    • JavaScript专题之jQuery通用遍历方法each的实现

    12.JavaScript 专题之如何判断两个对象相等

    • JavaScript 专题之如何判断两个对象相等

    构造函数,类的继承,混入

    两种类型的混入:1,显式;2,隐式

    示例:

    function mixin( sourceObj, targetObj ) {
     for (var key in sourceObj) {
      // 只会在不存在的情况下复制
      if(!(key in targetObj)) {
       targetObj[key] = sourceObj[key];
      }
     }
     return targetObj;
    }
    
    var Vehicle = {
     engines: 1,
     ignition: function() {
      console.log("truing on my engine");
     },
     drive: function() {
      this.ignition();
      console.log("steering and moving forward!");
     }
    };
    var Car = mixin(Vehicle, {
     wheels: 4,
     drive: function() {
      Vehicle.drive.call(this); // 多态
      console.log(
       "Rolling on all" + this.wheels + "wheels"
      };
     }
    });
    

    显式混入模式的一种变体被称为“寄生继承”,它既是显式的又是隐式的。

    示例:

    function Vehicle() {
     this.engines = 1;
    }
    Vehicle.prototype.ignition = function() {
     console.log("turning on my engine");
    };
    Vehicle.prototype.drive = function() {
     this.ignition();
     console.log("steering and moving forward");
    };
    // 寄生类Car
    function Car() {
     var car = new Vehicle();
     car.wheels = 4;
     var vehDrive = car.drive;
     // 重写
     car.drive = function() {
      vehDrive.call(this);
      console.log("rolling on all" + this.wheels + "wheels");
      return car;
     }
     myCar.drive();
    

    示例:

    var Something = {
     cool: function() {
      this.greeting = "hello world";
      this.count = this.count ? this.count + 1 : 1;
     }
    };
    Something.cool();
    Something.greeting; / "hello world"
    Something.count; // 1
    
    var Another = {
     cool: function() {
      // 隐式把Something 混入Another
      Something.cool.call(this);
     }
    };
    
    Another.cool();
    Another.greeting; // "hello world"
    Another.count; // 1 (count不是共享状态)
    

    W3C标准事件流

    W3C标准事件流: 包含3个阶段,捕获阶段,目标阶段,冒泡阶段。

    1. 在捕获阶段,事件对象通过目标的祖先从窗口传播到目标的父级。
    2. 在目标阶段,事件对象到达事件对象的事件目标。
    3. 在冒泡阶段,事件对象以相反的顺序通过目标的祖先传播,从目标的父级开始,到窗口结束。
    4. 先从顶层对象 window 开始一路向下捕获,直到达到目标元素,其后进入目标阶段。
    5. 目标元素 div 接收到事件后开始冒泡到顶层对象 window
    6. 单击了<div>元素,则首先会进行事件捕获,此时事件按 window→document→<html>→<body> 的顺序进行传播
    7. 当事件对象传到 <div> 时进入目标阶段,接着事件对象又从目标对象传到 body,从而进入事件的冒泡阶段
    8. 事件对象按 <body>→<html>→document→window 的顺序传播事件。

    已阅冴羽大佬文章 | 创作者训练营第二期

    13.JavaScript 专题之函数柯里化

    • JavaScript 专题之函数柯里化

    14.JavaScript 专题之惰性函数

    • JavaScript 专题之惰性函数

    15.JavaScript专题之函数组合

    • JavaScript专题之函数组合

    16.JavaScript 专题之函数记忆

    • JavaScript 专题之函数记忆

    17.JavaScript专题之递归

    • JavaScript专题之递归

    18.JavaScript专题之乱序

    • JavaScript专题之乱序

    19.JavaScript专题之解读 v8 排序源码

    • JavaScript专题之解读 v8 排序源码

    JavaScript中的对象有一个特殊的[[Prototype]]内置属性,其实就是对于其他对象的引用。几乎所有的对象在创建时[[Prototype]]属性都会被赋予一个非空的值。

    • 使用in操作符来检查属性在对象中是否存在时,同样会查找对象的整条原型链。

    示例:

    var anotherObject = {
     a: 2
    };
    // 创建一个关联到anotherObject的对象
    var myObject = Object.create(anthorObject);
    for(var k in myObject) {
     console.log("found:" + k);
    }
    // found:a
    ("a" in myObject); // true
    

    所有普通的 [[Prototype]] 链最终都会指向内置的 Object.prototype

    所有的函数默认都会拥有一个名为 prototype 的公有并且不可枚举的属性,它会指向另一个对象

    function Foo() {
     // ...
    }
    Foo.prototype; // { }
    
    var a = new Foo();
    
    Object.getPrototypeOf( a ) === Foo.prototype; // true
    

    new Foo() 会生成一个新对象,这个新对象的内部链接 [[Prototype]] 关联 的是 Foo.prototype 对象

    Object.create(...)会创建一个新对象并把它关联到我们指定的对象,Object.create(null)会创建一个拥有空链接的对象,这个对象无法进行委托。

    由于这个对象没有原型链,所以instanceof操作符无法进行判断,因此总是会返回false。这些特殊的空[[Prototype]]对象通常被称为“字典”,它们完全不会受到原型链的干扰,非常适合用来存储数据。

    示例:

    // polyfill 代码
    if(!Object.create) {
     Object.create = function(o) {
      function F(){}
      F.prototype = o;
      return new F(); // 构造一个新对象进行关联
     };
    }
    

    示例:

    var anotherObject = {
     a: 2
    };
    
    var myObject = Object.create( anotherObject, {
     b: {
      enumerable: false,
      writable: true,
      configurable: false,
      value: 3
     },
     c: {
      enumerable: true,
      writable: false,
      configurable: false,
      value: 4
     }
    });
    myObject.hasOwnProperty( "a" ); // false
    myObject.hasOwnProperty( "b" ); // true
    myObject.hasOwnProperty( "c" ); // true
    myObject.a; // 2
    myObject.b; // 3
    myObject.c; // 4
    

    已阅冴羽大佬文章 | 创作者训练营第二期

    示例:

    var anotherObject = {
     cool: function() {
      console.log("cool");
     }
    };
    var myObject = Object.create(anotherObject);
    myObject.doCool = function() {
     this.cool(); // 内部委托
    };
    myObject.doCool(); // "cool"
    

    对象之间是通过内部的[[Prototype]]链关联的。

    示例:

    class Task {
     id;
     // 构造函数Task()
     Task(ID) { id = ID; }
     outputTask() {output(id); }
    }
    
    class XYZ inherits Task {
     label;
     // 构造函数 XYZ()
     XYZ(ID,Label) { super( ID ); label = Label; }
     outputTask() { super(); output( label ); }
    }
    
    class ABC inherits Task {
     // ...
    }
    

    推荐代码:

    Task = {
     setID: function(ID) { this.id = ID; },
     outputID: function() { console.log( this.id ); }
    };
    
    // 让 XYZ 委托 Task 
    XYZ = Object.create( Task );
    
    XYZ.prepareTask = function(ID,Label) {
    this.setID( ID );
    this.label = Label; 
    };
    
    
    XYZ.outputTaskDetails = function() {
    this.outputID(); console.log( this.label ); 
    };
    // ABC = Object.create( Task );
    

    面向对象:

    function Foo(who) {
    this.me = who; 
    }
    
    Foo.prototype.identify = function() {
    return "I am " + this.me; 
    };
    
    function Bar(who) { 
    Foo.call( this, who ); 
    }
    
    Bar.prototype = Object.create( Foo.prototype ); 
    
    Bar.prototype.speak = function() { 
    alert( "Hello, " + this.identify() + "." ); 
    };
    
    var b1 = new Bar( "b1" );
    var b2 = new Bar( "b2" ); 
    
    b1.speak();
    b2.speak();
    

    对象关联:

    Foo = { 
    
    init: function(who) {
    this.me = who; 
    },
    
    identify: function() {
    return "I am " + this.me; 
    } 
    
    };
    
    
    Bar = Object.create( Foo ); 
    Bar.speak = function() { 
    alert( "Hello, " + this.identify() + "." ); 
    };
    
    var b1 = Object.create( Bar ); 
    b1.init( "b1" ); 
    var b2 = Object.create( Bar );
    b2.init( "b2" ); 
    b1.speak(); 
    b2.speak();
    

    示例:

    // 父类
    function Controller() {
     this.errors = [];
    }
    Controller.ptototype.showDialog(title,msg) {
     // 给用户显示标题和消息
    };
    Controller.prototype.success = function(msg) {
     this.showDialog("Success", msg);
    };
    Controller.prototype.failure = function(err) {
     this.errors.push(err);
     this.showDialog("Error", err);
    };
    
    // 子类
    function LoginController() {
     Controller.call(this);
    }
    // 把子类关联到父类
    LoginController.prototype = Object.create(Controller.prototype);
    
    LoginController.prototype.getUser = function() {
     return document.getElementById("login_username").value;
    };
    LoginController.prototype.getPassword = function() {
     return docuemnt.getElementById("login_password").value;
    };
    
    LoginController.prototype.validateEntry = function(user, pw) {
     user = user || this.getUser();
     pw = pw || this.getPassword();
     
     if( !(user && pw) ) {
      return this.failure(
       "please enter a username & password!"
       );
     }
     else if( user.length<5) {
      return this.failuer(
       "password must be 5+ characters"
       );
     }
     // 如果执行到这里表示通过验证
     return true;
    };
    // 重写failure()
    LoginController.prototype.failure = function(err) {
     // "super" 调用
     Controller.prototype.failure.call(
      this,
      "Login invalid" + err
      );
     };
     // 子类
     function AuthController(login) {
      Controller.call(this);
      // 合成
      this.login = login;
     }
    // 把子类关联到父类
    AuthController.prototype = 
     Object.crate(Controller.prototype);
    
    AuthController.prototype.server = function(url, data) {
     return $.ajax({
      url: url,
      data: data
     });
    };
    AuthController.prototype.checkAuth = function() {
     var user = this.login.getUser();
     var pw = this.login.getPassword();
     
     if (this.login.validateEntry(user.pw)) {
     this.server( "/check-auth",{
     user: user,
     pw: pw
     } ) .then( this.success.bind( this ) ) 
     .fail( this.failure.bind( this ) );
     }
    };
    
    // 重写基础的 success() 
    AuthController.prototype.success = function() { 
    //“super”调用 
    Controller.prototype.success.call( this, "Authenticated!" ); 
    };
    
    // 重写基础的 failure() 
    AuthController.prototype.failure = function(err) { 
    //“super”调用 
    Controller.prototype.failure.call(
    this, 
    "Auth Failed: " + err 
    ); 
    };
    
    var auth = new AuthController();
    auth.checkAuth( 
    // 除了继承,我们还需要合成
    new LoginController() 
    );
    

    对象关联:

    var LoginController = { 
    errors: [], 
    
    getUser: function() {
    return document.getElementById( "login_username" ).value; 
    },
    
    getPassword: function() {
    return document.getElementById( "login_password" ).value; 
    },
    
    validateEntry: function(user,pw) { 
    user = user || this.getUser(); 
    pw = pw || this.getPassword();
    
    if (!(user && pw)) {
    return this.failure( "Please enter a username & password!" ); 
    }
    else if (user.length < 5) {
    return this.failure( "Password must be 5+ characters!" ); 
    }
    // 如果执行到这里说明通过验证
    
    return true; 
    },
    
    showDialog: function(title,msg) { 
    // 给用户显示标题和消息 
    },
    
    failure: function(err) {
    this.errors.push( err );
    this.showDialog( "Error", "Login invalid: " + err ); 
    } 
    };
    
    // 让 AuthController 委托 LoginController
    
    var AuthController = Object.create( LoginController ); 
    
    AuthController.errors = []; 
    
    AuthController.checkAuth = function() {
    var user = this.getUser();
    var pw = this.getPassword(); 
    if (this.validateEntry( user, pw )) {
    this.server( "/check-auth",{ 
    user: user,
    pw: pw 
    } ) .then( this.accepted.bind( this ) ) 
    .fail( this.rejected.bind( this ) ); 
    } 
    };
    
    AuthController.server = function(url,data) {
    return $.ajax( { 
    url: url, 
    data: data 
    } ); 
    };
    
    AuthController.accepted = function() {
    this.showDialog( "Success", "Authenticated!" ) 
    };
    
    AuthController.rejected = function(err) {
    this.failure( "Auth Failed: " + err ); 
    };
    

    示例:

    class Foo { methodName() { /* .. */ } }
    

    已阅冴羽大佬文章 | 创作者训练营第二期

    个人专题

    ?力扣 (LeetCode)题目

    • 两数之和,有效的括号,两数相加
    • 合并两个有序链表,删除排序数组中的重复项,JavaScript笔记
    • 力扣 (LeetCode)-最大子序和,JavaScript数据结构与算法(数组)
    • 力扣 (LeetCode)-栈,括号生成 |刷题打卡
    • 力扣 (LeetCode)-加一,队列 |刷题打卡
    • 力扣 (LeetCode)-合并两个有序数组,字典,散列表|刷题打卡
    • 力扣 (LeetCode)-对称二叉树,树|刷题打卡
    • 力扣 (LeetCode)-104. 二叉树的最大深度,图|刷题打卡
    • 排序,搜索,算法模式,算法复杂度 | 数据结构与算法综合笔记
    • 力扣 (LeetCode)-28. 实现 strStr()
    • 力扣 (LeetCode)-14. 最长公共前缀
    • 力扣 (LeetCode)-13. 罗马数字转整数

    ?掘金文章

    • 前端日常总结
    • 一份不可多得的TypeScript系统入门整理
    • JS葵花宝典秘籍笔记,为你保驾护航金三银四
    • TypeScript趁早学习提高职场竞争力
    • 前端模拟面试字数过23477万内容
    • JavaScript数据结构之链表 | 技术点评
    • JavaScript的数据结构-集合 |技术点评
    • 这是我的第一次JavaScript初级技巧
    • 一个合格的初级前端工程师需要掌握的模块笔记
    • 【初级】个人分享Vue前端开发教程笔记
    • localStorage和sessionStorage本地存储
    • HTML5中的拖放功能
    • 挑战前端知识点HTTP/ECMAScript
    • 前端170面试题+答案学习整理(良心制作)
    • 必学必会-音频和视频
    • 前端HTML5面试官和应试者一问一答
    • Vue.js笔试题解决业务中常见问题
    • 前端面试必备ES6全方位总结
    • 考前复习必备MySQL数据库(关系型数据库管理系统)
    • 长篇总结之JavaScript,巩固前端基础
    • 学习总结之HTML5剑指前端(建议收藏,图文并茂)
    • 前端必学必会-多媒体-本地存储-浏览器与服务器的交互-通信功能
    • 【建议?】记录一次BAT一线互联网公司前端JavaScript面试
    • Web页面制作基础
    • 【思维导图】前端开发-巩固你的JavaScript知识体系
    • 【图文并茂,点赞收藏哦!】重学巩固你的Vuejs知识体系
    • 【高能笔记】如何获得令人心动的前端offer | 掘金技术征文
    • 11期前端冲刺必备指南-执行上下文/作用域链/闭包/一等公民
    • 12期前端冲刺必备指南-HTTP/HTTPS/HTTP2/DNS/TCP/经典题
    • 13期前端冲刺必备指南-this/call/apply/bind(万字长文)
    • 14期-连肝7个晚上,总结了计算机网络的知识点!(共66条)
    • 熬夜总结了 “HTML5画布” 的知识点(共10条)
    • 16期-熬夜7天,我总结了JavaScript与ES的25个重要知识点!
    • 17期-什么是MySQL数据库?看这一篇干货文章就够了!
    • 18期-后端逆袭,一份不可多得的php学习指南
    • 19期-当你在百度搜索关键字的时候,哪个网站会排在最前面?今天给大家科普一下“网站SEO”
    • 前端学习总结,经验分享,项目经验分享过程 | 掘金技术征文-双节特别篇
    • 写给前端程序员的英文学习指南 | 掘金技术征文-双节特别篇
    • 【图文并茂,点赞收藏哦!】重学巩固你的Vuejs知识体系(上)
    • 【图文并茂,点赞收藏哦!】重学巩固你的Vuejs知识体系(下)
    • 【思维导图】前端开发JavaScript-巩固你的JavaScript知识体系
    • (一)熟练HTML5+CSS3,每天复习一遍
    • 面试官一上来就问我Chrome底层原理和HTTP协议(万字长文)
    • 2020 年「我与技术面试那些事儿」| 掘金年度征文
    • 【进阶】面试官问我Chrome浏览器的渲染原理(6000字长文)| 掘金年度征文
    • 2020年小程序开发-云开发技术总结 | 掘金年度征文
    • 腾讯位置服务开发应用 | 创作者训练营
    • 达达前端个人web分享92道JavaScript面试题附加回答 | 创作者训练营
    • 【这一年收到的书籍,感谢赠予!】一起回顾 2020,展望 2021 | 掘金年度征文
    • 哪吒闹海,席卷图文学习前端Flex布局-七日打卡
    • 针对CSS说一说|技术点评
    • 原来也没有那么难!Vue商城开发 | 技术点评

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

    点赞、收藏和评论

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

    我们下期见!

    • 技术创作者们,快来这里交作业啦 | 创作者训练营第二期

    下载网 » 已阅冴羽大佬文章 | 创作者训练营第二期

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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