javascript 忍者秘籍读书笔记(二)

闭包的私有变量

function Ninja() {
    let feints = 0;
    this.getFeints = function () {
        return feints
    };
    this.feint = function () {
        feints++;
        return feints
    }
}

let ninja1 = new Ninja();

每一个通过ninja1 构造函数创建的对象实例可以获得各自的实例方法,但是私有变量不允许直接访问,为什么要保持私有变量的引用?,因为这些私有变量并不是对象的私有属性,但是通过构造函数所创建的对象方法去访问这些变量
* 通过函数访问私有变量,而不是通过对象访问

生成器

function* weaponGenerator() {
    yield 1;
    yield 2;
    yield 3;
}

let a = weaponGenerator();
//for (const arrayElement of a) {
//    console.log(arrayElement);
//}
console.log(a.next());
// { value: 1, done: false }
while (!a.next().done) {
    console.log(a.next().value);
}

使用yield 操作付将执行全交给另一个生成器
function* weaponGenerator() {
    yield 1;
    yield* Ninja();
    yield 3;
}
function* Ninja() {
    yield 4;
    yield 5;
    yield 6;
}
let a=weaponGenerator();
console.log(a.next()); //{ value: 1, done: false }
console.log(a.next());//{ value: 4, done: false }
console.log(a.next());//{ value: 5, done: false }

promise

const ninja=new Promise((res,rej)=>{
    res("成功");
    rej("失败")
});
ninja.then(res=>{
    console.log(res);
}).catch(rej=>{
    console.log(rej);
})

原型

函数(Function)才有prototype属性,对象(除Object) 拥有__proto__
函数与函数之间的继承

原型继承
function Person(){}
Person.prototype.dance = function () {};

function Ninja(){}
Ninja.prototype = new Person();
const a = new Ninja();

继承

ES5继承

function Person(){}
Person.prototype.dance=function(){};

function Ninja(){}
Ninja.prototype=new Person();
Object.defineProperty(Ninja.prototype,"constructor",{
  enumerable:false,
  value:Ninja,
  writable:true
});

ES6继承

class Person{
  constructor(name) {
    this.name=name
  }
  dance(){
    return true;
  }
}
class Ninja extends Person{ //关键字 extends  实现继承
  constructor(name,weapon){
    super(name);
    this.weapon=weapon;
  }
}

原型对象

只要创建一个新函数,然后给该函数创建一个prototype属性,这个属性指向函数的原型对象

function Person{}
person.prototype.name="Nicholas"
var person1=new Person();

对象的访问

在函数中 getter与setter控制属性访问

function Ninja(){
  let skillLevel;
  //getter方法控制对私有变量的访问
  this.getSkill=()=>skillLevel;
  // getter 方法控制对私有变量的复制
  this.setSkill=value=>skillLevel=value;
}
let a=new Ninja();
a.setSkill('xiaoming');
console.log(a.getSkill());

在对象字面量中定义 getter 和setter

const a = {
  arr: ['yosi', 'xiao', 'hattori'],
  get firstGet() {
    return this.arr[0]
  },
  set firstSet(value) {
    return this.arr[0] = value
  }
};
a.firstSet='lisi';// set 应该是赋值表达式的右边部分
console.log(a.firstGet);

ES6的class使用getter和seter

class Ninja{
  constructor(){
    this.arr = ['a', 'b', 'c'];
  }
  get firstNinja(){
    return this.arr[0]
  }
  set firstNinja(value){
    this.arr[0]=value
  }
}

let a = new Ninja();
a.firstNinja='d';
console.log(a.firstNinja);

Object.defineProperty定义getter和setter方法

function Ninja(){
  let a=0;
  Object.defineProperty(this,'a',{
    get(){
      return a
    },
    set(value){
      a=value
    }
  })
}
let nin = new Ninja();
nin.a=2;
console.log(nin.a);

使用getter与setter校验属性值

function Ninja(){
  let a=0;
  Object.defineProperty(this,'a',{
    get(){
      return a
    },
    set(value){
      if (!Number.isInteger(value)) {
        throw new TypeError('不是整数')
      }
      a=value
    }
  })
}
const p = new Ninja();
p.a='s';//报错
console.log(p.a);

使用getter与setter定义计算属性值

const a={
  name:'xiaoming',
  age:12,
  get getAll(){
    return this.name+'---'+this.age
  },
  set setAll(value){
    const segments = value.split('');
    this.name=segments[0];
    this.age = segments[1];
  }
};
a.setAll = 'ab';
console.log(a.getAll); // a---b
console.log(a.name); //a
console.log(a.age); //b

Proxy

Proxy 对象对于定义基本操作的自定义行为
语法
let p=new Proxy(target,handler);
参数
target  目标对象
handler 一个对象,其属性是执行操作的行为函数

给不存在属性名,返回数为37
let handler={
  get(target,name){
    return name in target?target[name]:37;
  }
};
let p = new Proxy({}, handler);
p.a=1;
p.b=2;
console.log(p.c);//37

---------
const a = {name: 'lisi'};
const rep = new Proxy(a, {
  get(target, key) {
    return key in target ? target[key] : '报错啦';
  },
  set(target, key, value) {
    return target[key] = value
  }
});
rep.s=1;
console.log(rep.l);//报错了

----------
function Ninja() {
  let a = 0;
  Object.defineProperty(this,'a',{
    get(){
      return a
    },
    set(value){
      a=value
    }
  })
}

const nin = new Ninja();
nin.a=2;
console.log(nin.a);
-------
function makeLoggable(target){
  return new Proxy(target,{
    get(target,key){
      return target[key]
    },
    set(target,key,value){
      target[key]=value
    }
  })
}
let ninja={name: 'xiaoming'};
let a = makeLoggable(ninja);
a.sex = '男';
console.log(a);

------
function Folder() {
  return new Proxy({}, {
    get(target, key) {
      if (!(key in target)) {
        target[key] = new Folder();
      }//如果对象不具有该属性,则创建该属性
      return target[key]
    }
  })
}

const rootFolder = new Folder();
try {
  rootFolder.name.sss.ggg.ddd = 'xxx';//不会报错
} catch (e) {
  fail('报错!')
}

使用代理实现数组负索引

const ninjas = ['a', 'b', 'c'];

console.log(ninjas[-2]);//js不支持数组负索引
console.log(ninjas.slice(-1));

function createArray(array) {
  if (!Array.isArray(array)) {
    throw new TypeError('不是数组,报错')
  }
  return new Proxy(array,{
    get(target,key){
      key=+key;
      return target[key < 0 ? target.length + key : key];
    },
    set(target, key, value) {
      key=+key;
      return target[key<0?target.length+key:key]=value
    }
  })
}

const arr = ['a', 'b', 'c', 'd'];
const proxyArr = createArray(arr);
console.log(proxyArr[-2]);

创建数组

创建数组有两种方式
内置Array构造函数
const arr=[1,2,3,4]
使用数组字面量
const sum=new Array('a','b','c')

push pop   比 shift,unshift  快

模块化

# 使用对象,闭包和立即执行函数实现模块
ES6模块

export const ninja='xiaoming'  导出
export default xxxx            默认导出
export {name as xxx}           别名导出

import {name,age} from 'xxx'   导入命令导出
import * as xxx from 'xxx'     导入模块中声明的全部内容

###############...............................................................................................................................................................................................................................................................................

posted @ 2019-05-08 15:22  猫神甜辣酱  阅读(495)  评论(0编辑  收藏  举报