• 12、Set、Map、Proxy、 Reflect、ts泛型、Iterator(遍历)、Generator(生成)、async、await、promise模拟、多态、原型链、create、defineProperty、parseFloat、jQuery之鼠标跟随、文档树效果、选项卡、全选、反选、四种宽获取、实例无new构建、业务逻辑


    来源 http://caibaojian.com/es6
    一、Set和Map
    1、Set:ES6提供的新的数据结构,类似于数组,但是成员的值都是唯一的,没有重复的。
    2、Map:ES6提供的新的数据结构,类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
    
    二、Proxy(内部拦截)
    1、Proxy实例(Proxy必须针对Proxy实例进行操作,否则Proxy不起作用)
    (1)实例一
    var obj = {};
    var thisObj = new Proxy(obj, {
      get: function (target, key, receiver) {
        console.log(obj === target); //true
        if (key === 4) {
          return 5;
        }
        return 6;
      },
      set: function (target, key, value, receiver) {
        return Reflect.set(target, key, value, receiver);
      },
      has: function (target, key) {
        if (key[0] === "c") {
          return false;
        }
        return key in target;
      },
    });
    thisObj.count = 1;
    console.log(thisObj.count);
    console.log("count" in thisObj);
    (2)实例二
    var fn=function(){ };
    var thisFn = new Proxy(fn,{
      construct:function(target,args){
        console.log(target===fn)//true
        return { value: args[0]*10 }//construct方法返回的必须是一个对象,否则会报错。
      }
    });
    console.log(new thisFn(1));
    console.log(Reflect.construct(thisFn,[1]));
    2、Proxy配置
    (1get(target, propKey, receiver)
    拦截对象属性的读取,比如proxy.starFunction 和 proxy['starFunction']。
    如果propKey属性部署了读取函数,则读取函数的this绑定receiver(一个对象)。
    (2set(target, propKey, value, receiver)
    拦截对象属性的设置,比如proxy.starFunction = v或proxy['starFunction'] = v,返回一个布尔值。
    (3)has(target, propKey)
    拦截propKey in proxy的操作,以及对象的hasOwnProperty方法,返回一个布尔值。
    (4)deleteProperty(target, propKey)
    拦截delete proxy[propKey]的操作,返回一个布尔值。
    (5)ownKeys(target)
    拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy),返回一个数组。该方法返回对象所有自身的属性,而Object.keys()仅返回对象可遍历的属性。
    (6)getOwnPropertyDescriptor(target, propKey)
    拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
    (7)defineProperty(target, propKey, propDesc)
    拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
    (8)preventExtensions(target)
    拦截Object.preventExtensions(proxy),返回一个布尔值。
    (9)getPrototypeOf(target)
    拦截Object.getPrototypeOf(proxy),返回一个对象。
    (10)isExtensible(target)
    拦截Object.isExtensible(proxy),返回一个布尔值。
    (11)setPrototypeOf(target, proto)
    拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。
    如果目标对象是函数,那么还有两种额外操作可以拦截。
    (12)apply(target, object, args)
    拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...) 。
    (13)construct(target, args)
    拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。
    
    三、Reflect(外部操纵)
    1、Reflect概述
    Reflect对象与Proxy对象一样,也是ES6为了操作对象而提供的新API。Reflect对象的设计目的有这样几个。
    (1) 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。
    (2) 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。
    (3) 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。
    (4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。
    2、Reflect方法
    (1)Reflect.get(target, name, receiver)
    查找并返回target对象的name属性,如果没有该属性,则返回undefined。
    如果name属性部署了读取函数,则读取函数的this绑定receiver。
    var antzone = {
      webName: "蚂蚁部落",
      url:"www.softwhy.com",
      get age() { return this.myAge; }
    }
    console.log(Reflect.get(antzone, "age", { myAge: 4 }));
    (2)Reflect.set(target, name, value, receiver)
    设置target对象的name属性等于value。如果name属性设置了赋值函数,则赋值函数的this绑定receiver。
    (3)Reflect.has(obj, name)
    等同于name in obj。
    (4)Reflect.deleteProperty(obj, name)
    等同于delete obj[name]。
    (5)Reflect.construct(target, args)
    等同于new target(...args),这提供了一种不使用new,来调用构造函数的方法。
    function func1(a, b, c) {
      this.sum = a + b + c;
    }
    const args = [1, 2, 3];
    const object1 = new func1(...args);
    const object2 = Reflect.construct(func1, args);
    console.log(object2.sum);//expected output: 6
    console.log(object1.sum);//expected output: 66)Reflect.getPrototypeOf(obj)
    读取对象的__proto__属性,对应Object.getPrototypeOf(obj)。
    (7)Reflect.setPrototypeOf(obj, newProto)
    设置对象的__proto__属性,对应Object.setPrototypeOf(obj, newProto)。
    (8)Reflect.apply(fun,thisArg,args)
    等同于Function.prototype.apply.call(fun,thisArg,args)。一般来说,如果要绑定一个函数的this对象,可以这样写fn.apply(obj, args),但是如果函数定义了自己的apply方法,就只能写成Function.prototype.apply.call(fn, obj, args),采用Reflect对象可以简化这种操作。
    console.log(Reflect.apply(Math.floor, undefined, [1.75]));// expected output: 1
    
    四、ts泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
    1、泛型函数的类型与非泛型函数的类型没什么不同,只是有一个类型参数在最前面,像函数声明一样.
    function createArray<T>(length: number, value: T): Array<T> {
      let result: T[] = [];
      for (let i = 0; i < length; i++) {
        result[i] = value;
      }
      return result;
    }
    createArray<string>(3, 'x'); // ['x', 'x', 'x']
    2、泛型参数的默认类型
    function createArray<T = string>(length: number, value: T): Array<T> {
      let result: T[] = [];
      for (let i = 0; i < length; i++) {
        result[i] = value;
      }
      return result;
    }
    3、泛型接口
    interface CreateArrayFunc {
      <T>(length: number, value: T): Array<T>;
    }
    let createArray: CreateArrayFunc;
    createArray = function<T>(length: number, value: T): Array<T> {
      let result: T[] = [];
      for (let i = 0; i < length; i++) {
        result[i] = value;
      }
      return result;
    }
    createArray(3, 'x'); // ['x', 'x', 'x']
    4、也可以把泛型参数提前到接口名上
    interface CreateArrayFunc<T> {
      (length: number, value: T): Array<T>;
    }
    let createArray: CreateArrayFunc<any>;
    createArray = function<T>(length: number, value: T): Array<T> {
      let result: T[] = [];
      for (let i = 0; i < length; i++) {
        result[i] = value;
      }
      return result;
    }
    createArray(3, 'x'); // ['x', 'x', 'x']
    5、泛型类
    TypeScript的核心原则之一是对值进行类型检查。
    在TypeScript里,接口的作用就是为这些类型命名和为代码定义契约。
    https://www.tslang.cn/docs/handbook/interfaces.html
    class GenericNumber<T> {
      zeroValue: T;
      add: (x: T, y: T) => T;
    }
    let myGenericNumber = new GenericNumber<number>();
    myGenericNumber.zeroValue = 0;
    myGenericNumber.add = function(x, y) { return x + y; };
    6、泛型约束
    interface Lengthwise {
        length: number;
    }
    
    function loggingIdentity<T extends Lengthwise>(arg: T): T {
        console.log(arg.length);
        return arg;
    }
    7、对泛型进行约束,只允许这个函数传入那些包含 length 属性的变量
    我们定义一个接口来描述约束条件。 创建一个包含 .length属性的接口,使用这个接口和extends关键字来实现约束。
     
    五、Iterator(遍历器)
    //以下遍历器(迭代器)模拟代码
    function createIterator(items) {
      var i = 0;
      return {
          next: function() {
              var done = (i >= items.length);
              var value = done ? undefined : items[i++] ;
              return {
                  done: done,
                  value: value
              };
          }
      };
    }
    var iterator = createIterator([1, 2, 3]);
    console.log(iterator.next()); // "{ value: 1, done: false }"
    console.log(iterator.next()); // "{ value: 2, done: false }"
    console.log(iterator.next()); // "{ value: 3, done: false }"
    console.log(iterator.next()); // "{ value: undefined, done: true }"
    JavaScript原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6又添加了Map和Set。这样四种数据结构只要部署了Iterator接口,就是”可遍历的“(iterable)。ES6规定,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。
    const obj = {
      [Symbol.iterator] : function () {
        return {
          next: function () {
            return {
              value: 1,
              done: true
            };
          }
        };
      }
    };
    上面代码中,对象obj是可遍历的(iterable),因为具有Symbol.iterator属性。
    
    六、Generator 函数(生成器)
    1、Generator函数有两个特征
    (1)function关键字与函数名之间有一个星号;
    (2)函数体内部使用yield(即“产出”)语句,定义不同的内部状态。
    2、调用Generator函数后,该函数并不执行,返回的是一个指向内部状态的指针对象,也就是遍历器对象(Iterator Object)。
    3、调用遍历器对象的next方法,使得指针移向下一个状态。
    4、也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield语句(或return语句)为止。
    5、换言之,Generator函数是分段执行的,yield语句是暂停执行的标记,而next方法可以恢复执行。
    6、示例1
    function* starFunction(one) {
      console.log(one);
      var two = 2 * (yield one + 1); //6,7
      console.log("1111111111111111111111111111111");
      console.log(two);
      var three = yield 2 * two; //4,8
      console.log("2222222222222222222222222222222");
      console.log(three);
      var four = yield 2 * three; //2,4
      console.log("3333333333333333333333333333333");
      console.log(four);
      console.log(one, two, three, four);
      console.log("4444444444444444444444444444444");
      return one + two + three + four;
    }
    var useFunction = starFunction(6);
    console.log(useFunction.next());
    console.log(useFunction.next(2));
    console.log(useFunction.next(2));
    console.log(useFunction.next(2));
    next第1次执行,返回“第1个yield语句的计算结果”;
    next第2次执行,返回“第2个yield语句的计算结果”,传入的参数取代“第1个yield语句的计算结果”;
    next第3次执行,返回“第3个yield语句的计算结果,传入的参数取代“第2个yield语句的计算结果””;
    next第n次执行时,如果没有第n个yield语句,那就一直执行到return,如果没有return,就返回undefined。
    7、示例2   
    来源:http://www.ruanyifeng.com/blog/2015/04/generator.html
    Fetch模块返回的是一个Promise对象,因此要用then方法调用下一个next方法。
    var fetch = require('node-fetch');
    function* generatorFn(){
      var urlA = 'https://api.github.com/users/githubA';
      var urlB = 'https://api.github.com/users/githubB';
      yield fetch(urlA);
      yield fetch(urlB);
    }
    var generatorOne = generatorFn();
    var result = generatorOne.next();
    result.value.then(function(data){
      return data.json();
    }).then(function(data){
      generatorOne.next(data);
    });
    8、如果想要第一次调用next方法时,就能够输入值,可以在Generator函数外面再包一层。如下
    function wrapper(generatorFunction) {
      return function (num) {
        let generatorObject = generatorFunction(num);
        generatorObject.next();
        return generatorObject;
      };
    }
    const wrapped = wrapper(function* starFunction(a) {
      console.log(a);
      var b = 2 * (yield a + 1); //6,7
      console.log("1111111111111111111111111111111");
      console.log(b);
      var c = yield 2 * b; //4,8
      console.log("2222222222222222222222222222222");
      console.log(c);
      var d = yield 2 * c; //2,4
      console.log("3333333333333333333333333333333");
      console.log(d);
      console.log(a, b, c, d);
      console.log("4444444444444444444444444444444");
      return a + b + c + d;
    });
    var b = wrapped(6);
    console.log(b.next(2));
    console.log(b.next(2));
    console.log(b.next(2));
    
    七、async(then)函数及其内部的await(promise)指令
    (1)async函数可以包含await指令,该指令会暂停原异步函数的执行,并等待右侧Promise返回结果;
    (2)若 Promise 正常处理,其回调resolve函数的参数作为 await 表达式的值;
    示例一:
    function thisPromise(x) {
      return new Promise(function (resolve) {
        //此处把x(加工后)作为参数向后台发送请求
        setTimeout(function () {
          //此处获得后台返回结果并加工为x+50,通过resolve暴露出去
          resolve(x + 50);
        }, 500);
      });
    }
    async function thisAdd(x) { //var thisAdd = async function(x) {
      var a = await thisPromise(20);
      var b = await thisPromise(30);
      //此处可以加工a,b
      return x + a + b; //这个结果作为参数传给后面的then参数
    }
    thisAdd(10).then(function (total) {
      console.log(total); //1 秒后出打印结果
    });
      
    八、promise内部机制模拟和校验
    //1、promise模拟
    function custPromise(callback) {
      this.value = null;
      this.status = "pending";
      this.cbArray = [];
      callback(this.resolve.bind(this));
    }
    custPromise.prototype.then = function (success) {
      var that = this;
      if (this.status == "pending") {//success为异步函数时
        return new custPromise(function (resolve) {//同步将then参数放在实例参数里
          that.cbArray.push(function () {//push参数就是下面的callbackIn
            var result = success(that.value);//success来自哪个实例,that.value就来自哪个实例
            if (result instanceof custPromise) {
              result.then(resolve);
            } else {
              resolve(result); //上面result.then(resolve)执行时,产生了这里的resolve
            }
          });
        });
      }
      if (this.status == "resolve") {//success为同步函数时
        return new custPromise(function (resolve) {
          var result = success(that.value);
          if (result instanceof custPromise) {
            result.then(resolve);
          } else {
            resolve(result);
          }
        });
      }
    };
    custPromise.prototype.resolve = function (value) {
      this.value = value;
      this.status = "resolve";
      if (this.cbArray.length > 0) {
        this.cbArray.forEach(function (callbackIn) {
          callbackIn(); //callbackIn就是上面的push参数
        });
      }
    };
    //2、promise验证
    //第1个上实例的自身参数为异步时,它的then参数为异步或同步的情况
    //第1个上实例的自身参数为同步时,它的then参数为异步或同步的情况
    new custPromise(function (resolve) {
      setTimeout(function () {
        resolve(1);
      }, 2000);
    })
    .then(function (value) {
      return new custPromise(function (resolve) {
        setTimeout(function () {
          resolve(value * 2);
        }, 1000);
      });
    })
    .then(function (value) {
      return new custPromise(function (resolve) {
        setTimeout(function () {
          resolve(value * 2);
        }, 1000);
      });
    })
    .then(function (value) {
      return new custPromise(function (resolve) {
        resolve(value * 2);
      });
    })
    .then(function (value) {
      return new custPromise(function (resolve) {
        resolve(value * 2);
      });
    })
    .then(function (value) {
      return value * 2;
    })
    .then(function (value) {
      console.log(value)
    });
    
    九、多态
    同一操作作用于不同的对象上面,可以产生不同的执行结果。比如你说“叫”,鸭子听了会发出“嘎嘎声”,鸡听了会发出“咯咯声”。
    1、非多态代码示例
    var makeSound = function(animal) {
      if(animal instanceof Duck) {
        console.log('嘎嘎嘎');
      } else if (animal instanceof Chicken) {
        console.log('咯咯咯');
      }
    }
    var Duck = function(){}
    var Chiken = function() {};
    makeSound(new Chicken());
    makeSound(new Duck());
    2、多态的代码示例
    var makeSound = function(animal) {
      animal.sound();
    }
    var Duck = function(){}
    Duck.prototype.sound = function() {
      console.log('嘎嘎嘎')
    }
    var Chiken = function() {};
    Chiken.prototype.sound = function() {
      console.log('咯咯咯')
    }
    makeSound(new Chicken());
    makeSound(new Duck());
    十、原型链
    (1)函数类或对象类或普通函数_的原型(直接找原型,简单)
    (2)函数类或对象类或普通函数或普通对象_所在类的原型(先找类再找原型,复杂)
    (3)函数类或对象类或普通函数或普通对象_所在类的原型_之所在类的原型...(先找类再找原型,复杂)
    var obj = {}
    function fn(){}
    1、函数类或对象类或普通函数的原型
    (1)Object.prototype={};
    (2)Function.prototype={};
    (3)fn.prototype = {};
    2、函数类或对象类或普通函数或普通对象_所在类的原型
    (1)Function.__proto__ === Function.prototype
    (2)Object.__proto__ === Function.prototype
    (3)fn.__proto__ === Function.prototype;
    (4)obj.__proto__ === Object.prototype;
    3、函数类或对象类或普通函数或普通对象_所在类的原型_之所在类的原型...
    (1)Function.__proto__.__proto__ === Function.prototype.__proto__ === Object.prototype
    (2)Object.__proto__.__proto__ === Function.prototype.__proto__ === Object.prototype
    (3)Function.__proto__.__proto__.__proto__ === Function.prototype.__proto__.__proto__ === Object.prototype.__proto__ === null4)Object.__proto__.__proto__.__proto__ === Function.prototype.__proto__.__proto__ === Object.prototype.__proto__ === null
    4、new出来的对象
    function AAA() {}
    AAA.prototype.bbb = function () {};
    var aaa = new AAA();
    console.log(aaa.__proto__ === AAA.prototype);
    console.log(aaa.__proto__.__proto__ === Object.prototype);
    //https://www.jianshu.com/p/686b61c4a43d
    附:原型链继承
    Drag.prototype.__proto__ = EventEmitter.prototype;//这是更安全的继承方法,一般在Node里都是采用这种方式实现继承。IE不支持
    Drag.prototype = new EventEmitter;//相对这种方式来说,上边的写法更安全
    
    十一、Object.create(proto[, propertiesObject])
    1、参数
    (1)proto:新创建对象的原型对象
    (2)propertiesObject:新创建对象的(可)枚举属性
    2、返回值
    (1)一个新对象,带着指定的原型对象和属性
    3、实例
    var myProto={proto:1};
    var youProto={
      enumer:{
        enumerable: true,
        value: "custom"
      }
    };
    var thisProto=Object.create(myProto,youProto)
    console.log(thisProto)
    console.log(thisProto.enumer)
    console.log(thisProto.__proto__===myProto)
    
    十二、Object.defineProperty() 
    1、语法:Object.defineProperty(myObject, prop, descriptor)
    2、参数:
    (1)myObject要定义或修改的属性所在的对象
    (2)prop要定义或修改的属性的名称
    (3)descriptor要定义或修改的属性的描述符,包含A、configurable,B、enumerable,C、数据描述符(2项)或存取描述符(2项)
    3、返回值:myObject
    4、作用:定义或者修改myObject的属性
    5、configurable,默认为false。为true时,prop可删,描述符可改
    6、enumerable,默认为false。为true时,prop可枚举
    7、数据描述符:
    (1)value,属性值,可以是数值、对象、函数等,默认为 undefined。
    (2)writable,默认为false。为true时,prop可重写。
    8、存取描述符:
    (1get,属性的getter函数,当访问prop时,会调用此函数,该函数的返回值被用作属性值,默认为undefined。
    (2set,属性的setter函数,当属性值被修改时,会调用此函数,该函数接受1个参数,默认为undefined。
    示例一
    var myObj = { thisValue: 5 };
    Object.defineProperty(myObj, "key", {
      configurable: false,
      enumerable: false,
      value: function () {
        console.log(this);
        return this.key+1;
      },
      writable: true,
      //value: "myValue",
      //writable: false,
    });
    myObj.key = 5;
    console.log(myObj.key);
    示例二
    var myObj = { thisValue: 5 };
    Object.defineProperty(myObj, "key", {
      configurable: false,
      enumerable: false,
      get: function () {
        console.log(this);
        return key+2;
      },
      set: function (value) {
        console.log(this);
        key = value + 1;
      },
    });
    myObj.key = 5;
    console.log(myObj.key);
    附、vue响应式相关代码
    function def(obj, key, val, enumerable) {
      Object.defineProperty(obj, key, {
        configurable: true,
        enumerable: !!enumerable,
        value: val,
        writable: true,
      });
    }
    Object.defineProperty(obj, key, {
      configurable: true,
      enumerable: true,
      get: function reactiveGetter() {
        var value = getter ? getter.call(obj) : val;
        return value;
      },
      set: function reactiveSetter(newVal) {
        var value = getter ? getter.call(obj) : val;
        dep.notify();
      },
    });
    
    十三、与parseFloat()相关
    原文地址:https://yq.aliyun.com/ziliao/92498?spm=5176.8246799.blogcont.20.cUDmIE
    1、Number()
    (1)如果是Boolean值,true和false值将分别被转换为1和0。
    (2)如果是数字值,只是简单的传入和返回。
    (3)如果是null值,返回0。
    (4)如果是undefined,返回NaN。
    (5)如果是字符串:
    A、如果字符串中只包含数字时,将其转换为十进制数值,忽略前导0
    B、如果字符串中包含有效浮点格式,如“1.1”,将其转换为对应的浮点数字,忽略前导0
    C、如果字符串中包含有效的十六进制格式,如“0xf”,将其转换为相同大小的十进制数值
    D、如果字符串为空,将其转换为0
    E、如果字符串中包含除上述格式之外的字符,则将其转换为NaN
    (6)如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再依照前面的规则转换返回的字符串值。
    例: 
    var num1 = Number("Hello world");       //NaN
    var num2 = Number("");            //0
    var num3 = Number("0000011");        //11
    2、parseInt()
    (1)处理整数的时候parseInt()更常用。parseInt()函数在转换字符串时,会忽略字符串前面的空格,知道找到第一个非空格字符。
    (2)如果第一个字符不是数字或者负号,parseInt() 就会返回NaN,同样的,用parseInt() 转换空字符串也会返回NaN。
    (3)如果第一个字符是数字字符,parseInt() 会继续解析第二个字符,直到解析完所有后续字符串或者遇到了一个非数字字符。
    (4)parseInt()方法还有基模式,可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。
    (5)基是由parseInt()方法的第二个参数指定的,所以要解析十六进制的值,当然,对二进制、八进制,甚至十进制(默认模式),都可以这样调用parseInt()方法。
    例:
    var num1 = parseInt("AF",16);           //175
    var num2 = parseInt("AF");            //NaN
    var num3 = parseInt("10",2);           //2  (按照二进制解析)
    var num4 = parseInt("sdasdad");         //NaN
    3、parseFloat()
    (1)与parseInt() 函数类似,parseFloat() 也是从第一个字符(位置0)开始解析每一个字符。也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。
    (2)也就是说,字符串中第一个小数点是有效的,而第二个小数点就是无效的了,它后面的字符串将被忽略。
    (3)parseFloat() 只解析十进制,因此它没有第二个参数指定基数的用法
    (4)如果字符串中包含的是一个可解析为正数的数(没有小数点,或者小数点后都是零),parseFloat() 会返回整数。
    例:
    var num1 = parseFloat("123AF");           //123
    var num2 = parseFloat("0xA");            //0
    var num3 = parseFloat("22.5");            //22.5
    var num4 = parseFloat("22.3.56");         //22.3
    var num5 = parseFloat("0908.5");          //908.5
    parseInt() 和parseFloat() 的区别在于:
    parseFloat() 所解析的字符串中第一个小数点是有效的,而parseInt() 遇到小数点会停止解析,因为小数点并不是有效的数字字符。
    parseFloat() 始终会忽略前导的零,十六进制格式的字符串始终会被转换成0,而parseInt() 第二个参数可以设置基数,按照这个基数的进制来转换。
    4、customParseInt:字符串类型的数字转换成数字类型的数字、数字类型的数字和字符串类型的非数字保持原样
    function customParseInt(num) {
      var tempNum = parseInt(num);
      if (typeof tempNum === 'number' && !isNaN(tempNum)) {
        return tempNum;
      }
      return num;
    };
    console.log(customParseInt(1))
    console.log(customParseInt("1"))
    console.log(customParseInt("闪烁"))
    4、整型范围
    (1)有负号整型范围
    Int8:[-128:127]
    Int16:[-32768:32767]
    Int32:[-2147483648:2147483647]
    Int64:[-9223372036854775808:9223372036854775807]
    (2)无负号整型范围 
    UInt8:[0:255]
    UInt16:[0:65535]
    UInt32:[0:4294967295]
    UInt64:[0:18446744073709551615]
    十四、jQuery实现鼠标跟随
    所谓鼠标跟随,一般就是指鼠标移到哪张图片上,那该张图片的放大图片就会出现,并且放大图片会随着鼠标在该张图片上移动而移动。
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title></title>
      <style>
        * {
          margin: 0;
          padding: 0;
        }
        img {
          border: none;
        }
        .box {
           660px;
          position: relative;
        }
        .box .mark {
          position: absolute;
           400px;
          height: 300px;
          display: none;
        }
        .box .mark img {
           100%;
        }
        .box img {
           150px;
          float: left;
          margin: 5px;
        }  
      </style>
    </head>
    <body>
    <div class="box" id="box">
      <img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=e95708d565639d99576ae7cb00729334" 
        realImg="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=5328802dc943fc046e109f70359add0a" alt=""/>
      <img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=9e5459a7c0098c27adf4bdd73889caa9" 
        realImg="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=846f4d1987765dc4cfd5a06fcdd2dcc1" alt=""/>
      <img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=3cd1c8e301007f0c94850139ac79cb5a" 
        realImg="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=747bf3f7092ebd2b0bf9fcd27e28bbe5" alt=""/>
      <img src="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=f391169b2cf678aa6fd253cf40d9821d" 
        realImg="http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=fec8d2f20fad1f28d540337a831e89d0" alt=""/>
      <div id="mark" class="mark"><img src="" alt=""/></div>
    </div>
    <script src="http://s0.kuaizhan.com/res/skin/js/lib/jquery-2.0.3.min.js"></script>
    <script>
      //1.鼠标移入哪张图片的时候,让他对应的大图显示;
      //2.当鼠标在img中移动的时候,大图跟着走;
      var $box=$('.box');
      var $aImg=$box.children('img');
      var $mark=$('.mark');
      var $offset=$box.offset();
      $aImg.mouseover(function(){
        //当鼠标移入每张图片的时候,让mark显示,并且,让mark里面的img标签,src属性值为当前这个图片的realImg属性上拿到的值;
        $mark.show().find('img').attr('src',$(this).attr('realImg'));
      });
      $aImg.mousemove(function(e){
        //拿鼠标的x坐标,减去$box距离body的left位置;
        var left= e.clientX-$offset.left+10;
        var top= e.clientY-$offset.top+10;
        $mark.css({left:left,top:top})
      });
      $aImg.mouseout(function(){
        $mark.hide();
      })
    </script>
    </body>
    </html>
    
    十五、jQuery实现文档树效果
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title></title>
      <style>
        * {
          margin: 0;
          padding: 0;
          list-style: none;
        }
        .box {
           250px;
          height: auto;
          padding: 20px;
          background: lightgrey;
          margin: 0 auto;
        }
        .box li {
          line-height: 30px;
          /*注意:height没有被设置,可以根据实际需要自动调整*/
          position: relative;
        }
        .box li em {
          position: absolute;
          left: 0;
          top: 7px;
           16px;
          height: 16px;
          background-image: url("");
          background-size: 100%;
          cursor: pointer;
        }
        .box li em.open {
          background-image: url("");
          background-size: 100%;
        }
        .box li span {
          padding-left: 20px;
          /*因为span前面的em已经绝对定位,脱离文档流了,所以span的左边界直达 li*/
        }
        .box ul {
          display: none;
        }
        .two {
          margin-left: 20px;
        }
        .three {
          margin-left: 40px;
        }
        .four {
          margin-left: 40px;
        }
        /*ul.box下的li显示,其中有折叠的li加em;
        ul.box下的ul隐藏,其内部的li是没法显示的*/
      </style>
    </head>
    <body>
    <ul class="box">
      <li><em></em><span>第一级第一个</span>
        <ul class="two">
          <li><span>第二级第一个</span></li>
          <li><em></em><span>第二级第二个</span>
            <ul class="three">
              <li><em></em><span>第三级第一个</span>
                <ul class="four">
                  <li><span>第四级第一个</span></li>
                  <li><span>第四级第二个</span></li>
                </ul>
              </li>
              <li><span>第三级第二个</span></li>
            </ul>
          </li>
          <li><em></em><span>第二级第三个</span>
            <ul class="three">
              <li><span>第三级第一个</span></li>
              <li><span>第三级第二个</span></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><em></em><span>第一级第一个</span>
        <ul class="two">
          <li><span>第二级第一个</span></li>
          <li><em></em><span>第二级第二个</span>
            <ul class="three">
              <li><em></em><span>第三级第一个</span>
                <ul class="four">
                  <li><span>第四级第一个</span></li>
                  <li><span>第四级第二个</span></li>
                </ul>
              </li>
              <li><span>第三级第二个</span></li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
    <script src="http://s0.kuaizhan.com/res/skin/js/lib/jquery-2.0.3.min.js"></script>
    <script>
      /*思路:
        * 1.让前面有em的span加上小手效果;
        * 2.点击span or em的时候,看他父容器下是否有ul,如果有,让其显示,否则,隐藏
        * */
      var $box=$('.box');
      var $aSpan=$box.find('span');
      //1.让前面有em的span加上小手效果;
      $aSpan.each(function(index,item){
        //if($(item).prev().length){ $(item).css('cursor','pointer');};思路1:
        $(item).prev('em').next('span').css('cursor','pointer'); //思路2:
      });
      //2.点击span or em的时候,看他父容器下是否有ul,如果有,让其显示,否则,隐藏
      $box.click(function(e){
        //当点击的事件源是em or span的时候,我们看其父级下是否有ul
        // 如果有:展开让其闭合,闭合就让其展开;
        if(e.target.tagName.toLowerCase()=='em' || e.target.tagName.toLowerCase()=='span'){
          var $parent=$(e.target).parent();
          var $ul=$parent.children('ul');
          if($ul){
            if($ul.css('display')=='block'){//展开,让其闭合
              //当闭合的时候,让当前容器下,所有的em都移除open,所有的ul都隐藏;
              $parent.find('ul').hide();
              $parent.find('em').removeClass('open');
            }else{ //闭合让其展开
              $ul.show();
              $parent.children('em').addClass('open');
    
            }
          }
        }
      })
    </script>
    </body>
    </html>
    
    十六、jQuery方法扩展(选项卡)
    在jQuery上扩展方法,通过点击实现选项卡的切换。本实例在jQuery的类上扩展,即$.extend({chooseCard:函数}),通过$.chooseCard('#box')调用;有别于$.fn.extend({chooseCard:函数})扩展,通过$().chooseCard('#box')调用。
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <style>
        * {
          margin: 0;
          padding: 0;
        }
        .box {
           312px;
          border: 2px red solid;
          margin: 0 auto;
        }
        ul {
          overflow: hidden;
        }
        li {
          list-style: none;
          background: red;
          float: left;
           100px;
          height: 30px;
          line-height: 30px;
          text-align: center;
          border: 2px solid orange;
        }
        li.on {
          background: green;
        }
        .box div {
          background: green;
          display: none;
           312px;
          height: 200px;
          font-size: 30px;
          border-top: none;
        }
        .box div.on {
          display: block;
        }
      </style>
    </head>
    <body>
    <div class="box" id="box">
        <ul>
          <li class="">中国</li>
          <li>日本</li>
          <li>韩国</li>
        </ul>
        <div class="on">中国是老大</div>
        <div>日本是老二</div>
        <div>韩国是老三</div>
    </div>
    <script src="http://s0.kuaizhan.com/res/skin/js/lib/jquery-2.0.3.min.js"></script>
    <script>
      (function ($) {
        $.extend({
          chooseCard: function (idStr) {
            var $box = $(idStr);
            var $li = $box.find("li");
            console.log($li);
            var $aDiv = $box.find("div");
            $li.click(function () {
              $(this)
                .css({ height: "32px", "border-bottom": "none" })
                .siblings("li")
                .css({ height: "30px", "border-bottom": "2px solid orange" });
              $(this).addClass("on").siblings("li").removeClass("on");
              $aDiv
                .eq($(this).index())
                .addClass("on")
                .siblings("div")
                .removeClass("on");
            });
          },
        });
      })(jQuery);
    </script>
    <script>
      $(function(){
        $.chooseCard('#box');
      })
    </script>
    </body>
    </html>
    
    十七、复选框全选、反选(<input type='checkbox'/>)
    (1)获取复选框状态:$("#allSelect").prop("checked")
    (2)改变复选框状态:$("#allSelect").prop("checked",false)
    (3)翻转复选框状态:item.checked = !item.checked;
    (4)判断复选框是否被选中:if ($(this).is(':checked'))
    (5)找到所有被选中的复选框:myDiv.find("input:checked");
    (6)获取所有复选框:$("#single input:checkbox")或$("#single input[type=checkbox]");
    (7)获取所有被选中的复选框:$("#single input:checkbox:checked")或$("#single input[type=checkbox]:checked");
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.9.0/jquery.js"></script>
    </head>
    <body>
    <span>全选</span><input type="checkbox" id="allSelect"><br>
    <span>反选</span><input type="checkbox" id="reverseSelect">
    <div id="single">
      <input type="checkbox">
      <input type="checkbox">
      <input type="checkbox">
      <input type="checkbox">
    </div>
    </body>
    </html>
    <script>
      $("#allSelect").click(function () {
        $("#single")
          .children()
          .each(function (index, item) {
            item.checked = $("#allSelect").prop("checked");
          });
        $("#reverseSelect").prop("checked", false);
      });
      $("#reverseSelect").click(function () {
        $("#single")
          .children()
          .each(function (index, item) {
            item.checked = !item.checked;
          });
        $("#reverseSelect").prop("checked", true);
        singleInput();
      });
      $("#single")
        .children()
        .click(function (index, item) {
          $("#reverseSelect").prop("checked", false);
          singleInput();
        });
      function singleInput() {
        if (
          $("#single input:checkbox:checked").length ==
          $("#single input:checkbox").length
        ) {
          $("#allSelect").prop("checked", true);
        } else {
          $("#allSelect").prop("checked", false);
        }
      }
    </script>
    
    十八、jQuery中的width()、innerWidth()、outerWidth()的区别总结
    (1)width():其宽度范围是所匹配元素的宽度width;
    (2)innerWidth():其宽度范围是所匹配元素的宽度width+padding;
    (3)outerWidth():其宽度范围是所匹配元素的宽度width+padding+border;
    (4)outerWidth(true)其宽度范围是所匹配元素的宽度width+padding+border+margin;
    
    十九、jQuery实例无new构建
    (function(window) {
      var jQuery = function(selector, context) {
        return new jQuery.prototype.init(selector, context, rootjQuery);
      }, 
      jQuery.prototype = {
        init: function( elem, options, prop, end, easing, unit ) {
          this.elem = elem;
          this.prop = prop;
          this.easing = easing || jQuery.easing._default;
          this.options = options;
          this.start = this.now = this.cur();
          this.end = end;
          this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
        },
      }
      jQuery.prototype.init.prototype = jQuery.prototype;
    })(window);
    
    二十、业务逻辑
    (1)不同的项目有不同的功能,不同的功能需要不同的实现,实现这些核心功能的代码就叫业务逻辑。
    (2)实现核心功能的代码就叫业务逻辑。
     
  • 相关阅读:
    Linux-nmap
    MongoDb注意事项
    HTML如何转XTML
    Centos 64位 Install certificate on apache 即走https协议
    CentOS 下搭建部署独立SVN服务器全程详解(5.5)
    LNMP安装与配置
    64位CentOS 6.0下搭建LAMP环境
    Apache遇到的问题:APR not found
    超详细LAMP环境搭建
    偏方治百病
  • 原文地址:https://www.cnblogs.com/gushixianqiancheng/p/11929936.html
Copyright © 2020-2023  润新知