js忍者秘籍

13 篇文章 0 订阅
9 篇文章 0 订阅

es速查表:

  • 生成器,一种可以基于一次请求生成多次值的函数,在不同请求之间也能挂起执行。
  • Promise,让我们更好地控制异步代码。
  • 代理,让我们控制对特定对象的访问。
  • 高级数组方法,书写更优雅的数组处理函数。
  • Map,用于创建字典集合;Set,处理仅包含不重复项目的集合。
  • 正则表达式,简化用代码书写起来很复杂的逻辑。
  • 模块,把代码划分为较小的可以自包含的片段,使项目更易于管理。
  • 通过下列方式https://kangax.github.io/compat-table/es6/、http://kangax. github. io/compat-table/es2016plus/以及 https://kangax.github.io/compat-table/esnext/进行查看,由此保持对浏览器支持状态的了解
  • 最流行的转换编译器是Traceur和Babel。使用如下教程可以很容易地配置它们:https://github.com/googLe/traceur-compiler/wiki/Getting-stanted或http://babeljs.io/docs/set

箭头函数sort排序:

   const values = [0, 3, 2, 5, 7, 4, 8, 1];

    let val1=values.sort((v1,v2)=> v1 - v2);//升序

    console.log(val1);// [0, 1, 2, 3, 4, 5, 7, 8]

    let val2=values.sort((v1,v2)=> v2 - v1);//降序

    console.log(val2); //8, 7, 5, 4, 3, 2, 1, 0]

 class静态方法:

    class Person {

     constructor(name){this.name = name; }

     dance(){return true; }

    }

    class Ninja extends Person {

     constructor(name, level){

       super(name);

       this.level = level;

     }

     static compare(ninja1, ninja2){//静态方法不会被实例继承

       return ninja1.level - ninja2.level;

     } 

    }

    let ninja = new Ninja('kobe',32);

    let a=Ninja.compare({level:9},{level:2});//通过类直接调用

    console.log(ninja,a);//Ninja {name: "kobe", level: 32} ,7

ps:想通过子类的静态方法调用父类的静态方法,需要在子类静态方法中的super对象上调用

桌面应用,通过使用如NW.js(http://nwjs.io/)或Electron (http://electron.atom.io/)的库可以开发桌面应用。这些技术通常通过包装浏览器使我们能用标准的HTML、CSS和JavaScript(我们可以完全依赖我们的核心JavaScript和浏览器知识来开发)以及一些额外的访问文件系统的能力来构建桌面应用。从而能够开发真正独立于平台的桌面应用,它和我们在Windows、Mac和Linux上见到的应用看起来一样。


移动应用,使用类似Apache Cordova (https://cordova.apache.org/)的框架开发。与使用 Web 技术构建桌面应用一样,该应用框架也包装了浏览器,不过其中还包含一些额外的针对特定平台的API,从而让开发者能与移动平台交互。
使用Node.js开发服务器端应用和嵌入式应用,Node.js是源自于浏览器的环境,使用了很多类似浏览器的底层原理。例如,Node.js 能执行 JavaScript 代码,并且也基于事件驱动。

3.3函数的定义

4个表达式都是立即调用函数表达式主题的4个不同版本:

+function(){}();
-function(){}();
!function(){}();
~function(){}();

4.2.3函数调用

当调用构造函数时会发生一系列特殊的操作,如图所示: 

构造函数的目的是创建一个新对象,并进行初始化设置,然后将其作为构造函数的返回值。任何有悖于这两点的情况都不适合作为构造函数。but如果构造函数返回一个对象,则该对象将作为整个表达式的值返回,而传入构造函数的this将被丢弃;如果构造函数返回的是非对象类型,则忽略返回值,返回新创建的对象。

4.2函数调用

作为函数直接被调用:函数上下文(this关键字的值)有两种可能性:在非严格模式下,它将是全局上下文(window对象),而在严格模式下,它将是undefined;

作为方法被调用:当函数作为某个对象的方法被调用时,该对象会成为函数的上下文(this——>对象)

作为构造函数被调用:如果构造函数返回一个对象,则该对象将作为整个表达式的值返回,而传入构造函数的this将被丢弃。

但是,如果构造函数返回的是非对象类型,则忽略返回值,返回新创建的对象。

使用apply和call调用

  • 如果作为函数调用,在非严格模式下,this指向全局window对象;在严格模式下,this指向undefined。
  • 作为方法调用,this通常指向调用的对象。
  • 作为构造函数调用,this指向新创建的对象。
  • 通过call或apply调用,this指向call或apply的第一个参数。

案例1:

var ninja1 = {    

    a:1,

  whoAmI: function(){     

   return this;    

  } 

};   

var ninja2 = { 

    a:2,   

 whoAmI: ninja1.whoAmI 

}; 

var identify = ninja2.whoAmI;

console.log(identify(),ninja2.whoAmI(),ninja1.whoAmI());//window,ninja2,ninja1 函数调用、方法调用、方法调用

案例2:

function Ninja(){

 this.whoAmI = () => this; 

}

var ninja1 = new Ninja(); 

var ninja2 = { 

 whoAmI: ninja1.whoAmI //ninja1

};

console.log(ninja1.whoAmI()==ninja1,ninja2.whoAmI()==ninja2);//true构造函数调用指向新对象; false ninja1.whoAmI()

5闭包

5.1每一个通过闭包访问变量的函数都具有一个作用域链,作用域链包含闭包的全部信息。使用闭包时,所有的信息都会存储在内存中。

5.2封装私有变量 闭包内部的变量可以通过闭包内的方法访问,构造器外部的代码则不能访问闭包内部的变量。

var声明的变量实际上总是在距离最近的函数内或全局词法环境中注册的,不关注块级作用域,例如for循环中的i,在循环外也可以访问。

7.2.3通过构造函数实现对象类型

1.每个函数都具有prototype属性,该函数创建的对象的原型就是函数的原型。

   每个函数都具有一个原型对象,每个函数的原形对象都具有一个constructor属性,该属性指向函数本身。

2.constructor属性仅仅是原始构造函数本身的引用。

3.一个完整的原型链:一个对象的原形是另一个对象的实例。ps:Ninja.prototype = new Person()

4.Object.setPrototypeOf(yoshi, hattori);   ⇽---  Object. setProto-typeOf方法,将对象hattori设置为yoshi对象的原型

7.3 配置对象的属性:

  • configurable —— 如果设为true,则可以修改或删除属性。如果设为false,则不允许修改。
  • enumerable —— 如果设为true,则可在for-in循环对象属性时出现(我们很快会介绍for-in循环)。
  • value —— 指定属性的值,默认为undefined。
  • writable —— 如果设为true,则可通过赋值语句修改属性值。
  • get —— 定义getter函数,当访问属性时发生调用,不能与value与writable同时使用。
  • set —— 定义setter函数,当对属性赋值时发生调用,也不能与value与writable同时使用。
  • Object.defineProperty(Ninja.prototype, "constructor", {//不希望丢失constructor
     enumerable: false,
     value: Ninja,
     writable: true  ⇽--- 定义一个新的不可枚举的constructor属性,属性值为Ninja
    });

7.4.2class 实现继承

1.对所有实例都可访问的方法必须直接添加在构造函数的原型上。

2.在ES6中实现继承:

class Person {
 constructor(name){
   this.name = name;
 }

 dance(){//定义一个所有Person实例都可访问的方法
   return true;
 }
}

class Ninja extends Person {  ⇽--- 使用关键字extends实现继承
 constructor(name, weapon){
   super(name);  ⇽--- 使用关键字super调用基类构造函数
   this.weapon = weapon;
 }

 wieldWeapon(){
  return true;
 }
}ES6转为ES5:
class Warrior {
  constructor(weapon) {
   this.weapon = weapon;
  }

  wield() {
   return "Wielding " + this.weapon;
  }

  static duel(warrior1, warrior2) {
   return warrior1.wield() + " " + warrior2.wield();
  }
}

 es5:function Warrior{this.weapon= weapon}

Warrior.porototype.wield=function(){return...} 

Warrior.duel=function(warrior1,warrior2){return ....}

8.1 Number.isinteger 可以判断是否为整数 Number.isInteger(26) // true

8.2使用代理控制访问 

每个getter和setter仅能控制单个对象属性,而代理可用于对象交互的通用处理,包括调用对象的方法。

8.2.2使用代理检测性能

function isPrime(number){//是否是素数
  if(number < 2) { return false; }
  for(let i = 2; i < number; i++) {
    if(number % i === 0) { return false; }
  }  ⇽--- 定义isPrime函数的简单实现
 return true;
}

isPrime = new Proxy(isPrime, {  ⇽--- 使用代理包装isPrime方法
 apply: (target, thisArg, args) => {  ⇽--- 定义apply方法,当代理对象作为函数被调用时将会触发该apply方法的执行
  console.time("isPrime");  ⇽--- 启动一个计时器,记录isPrime函数执行的起始时间

  const result = target.apply(thisArg, args);   ⇽--- 调用目标函数

  console.timeEnd("isPrime");  ⇽--- 停止计时器的执行并输出结果

  return result;
 }
});

isPrime(1299827);   ⇽--- 同调用原始方法一样,调用isPrime方法

带参数的 apply() 方法:

var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}
var person1 = {
  firstName:"John",
  lastName: "Doe"
}
person.fullName.apply(person1, ["Oslo", "Norway"]);

与 call() 方法对比:

var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}
var person1 = {
  firstName:"John",
  lastName: "Doe"
}
person.fullName.call(person1, "Oslo", "Norway");

 正则表达式

search() 方法:var str = "Visit Runoob!"; var n = str.search(/Runoob/i);//6下标

replace() 方法:var str = document.getElementById("demo").innerHTML; var txt = str.replace(/microsoft/i,"Runoob");

test()方法:var patt = /e/; patt.test("The best things in life are free!");//true

exec() 该函数返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。/e/.exec("The best things in life are free!");//输出匹配结果e

/[^abc]/:匹配一次不是abc的字符

/(?:ninja)-(trick)?-\1/.exec("ninja--")    true:问号加冒号(?:)是未捕获的分组;问号(?)尽可能少的匹配

导入导出:可以为默认导出,自定义导入名称 

计时器:使用0,意味着通知浏览器尽快执行回调,但与其他微任务不同,在回调之前可以执行页面渲染。允许浏览器更新UI,使得Web应用程序交互性更强.

setTimeout(generateRows, 0);这并不意味着将在0ms时执行回调.将超时延迟设置为0来表示下一次迭代应该“尽快”执行,但仍然必须在UI更新之后执行

13.3我们可以向addEventListener传递参数。第3个参数如果传入true,将采用事件捕获;如果传入false,则采用事件冒泡。因此,某种意义上来说,W3C 标准更倾向于优先选择事件冒泡,默认是事件冒泡。先从顶层开始查找捕获,然后再从底层查到冒泡。

注册事件处理器的方法是使用内置的addEventListener方法。this关键字指向的是事件处理器注册的元素(变动中),不一定是发生事件的元素(event.target)。

14跨浏览器开发技巧

在IE11和Firefox上对HTML元素使用scrollTop和scrollLeft属性,而在Safari、Chrome和Opera上则对body元素使用scrollTop和scrollLeft属性。

附录A

模板字符串: `Name: ${ninja.name} Action: ${ninja.action}`;
解构赋值:const {name, action, weapon} = ninja;
         const [firstNinja, secondNinja, thirdNinja] = ninjas;
         const [first, ...remaining] = ninjas;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值