温故知新之JS基本

数据范例

  1. NAN

    NaN === NaN; // false

    唯一能推断NaN的要领是经由过程isNaN()函数:

    isNaN(NaN); // true
  2. 浮点数的相称比较:

    1 / 3 === (1 - 2 / 3); // false

    这不是JavaScript的设想缺点。浮点数在运算过程中会发生偏差,因为盘算机没法准确示意无限轮回小数。要比较两个浮点数是不是相称,只能盘算它们之差的绝对值,看是不是小于某个阈值:

    Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true
  3. 防止运用new Array(1, 2, 3); // 建立了数组[1, 2, 3]体式格局

字符串

  1. 须要特别注重的是,字符串是不可变的
    假如对字符串的某个索引赋值,不会有任何毛病,然则,也没有任何结果:

    var s = 'Test';
    s[0] = 'X';
    alert(s); // s依然为'Test'
  2. JavaScript为字符串供应了一些经常使用要领,注重,挪用这些要领自身不会转变原有字符串的内容,而是返回一个新字符串

数组

  1. 大多数其他编程言语不许可直接转变数组的大小,越界接见索引会报错。但是,JavaScript的Array却不会有任何毛病。在编写代码时,不发起直接修正Array的大小,接见索引时要确保索引不会越界。

  2. 对原数组举行操纵的要领和返回新数组的要领
    原数组:

    • pop/push,unshift/shift

    • sort

    • reverse

    • splice

    新数组:

    • slice

    • concat

    join返回的是新的字符串

  3. 扩大:数组扁平化的几种要领

    var myArray = [[1, 2],[3, 4, 5], [6, 7, 8, 9]];
    • 运用concat()和apply()

      var myNewArray = [].concat.apply([], myArray);
      // [1, 2, 3, 4, 5, 6, 7, 8, 9]
    • 运用reduce()

      var myNewArray = myArray.reduce(function(prev, curr) {
        return prev.concat(curr);
      });
      // [1, 2, 3, 4, 5, 6, 7, 8, 9]

      MSDN reduce 要领

    • 运用 ES6 的睁开运算符

      var myNewArray4 = [].concat(...myArray);
      console.log(myNewArray4);
      // [1, 2, 3, 4, 5, 6, 7, 8, 9]

      MDN 睁开运算符

    • 末了这个要领返回的是字符串

      myArray.join(',')
      //"1,2,3,4,5,6,7,8,9"
  4. 请注重,for … in对Array的轮回获得的是String而不是Number

对象

  1. 注重,末了一个键值对不须要在末端加,,假如加了,有的浏览器(如低版本的IE)将报错。

  2. 接见属性是经由过程.操纵符完成的,但这要求属性名必需是一个有用的变量名

    var xiaohong = {
        name: '小红',
        'middle-school': 'No.1 Middle School'
    };

    xiaohong的属性名middle-school不是一个有用的变量,就须要用”括起来。接见这个属性也没法运用.操纵符,必需用[‘xxx’]来接见:

    xiaohong['middle-school']; // 'No.1 Middle School'
    xiaohong['name']; // '小红'
    xiaohong.name; // '小红'   
  3. 接见不存在的属性不报错,而是返回undefined

函数

  1. 警惕你的return语句

    假如把return语句拆成两行:

    function foo() {
        return
            { name: 'foo' };
    }
    
    foo(); // undefined

    要警惕了,因为JavaScript引擎在行末自动增加分号的机制,上面的代码现实上变成了:

    function foo() {
        return; // 自动增加了分号,相当于return undefined;
            { name: 'foo' }; // 这行语句已没法实行到了
    }

    所以准确的多行写法是:

    function foo() {
        return { // 这里不会自动加分号,因为{示意语句还没有完毕
            name: 'foo'
        };
    }
  2. 变量提拔
    因为JavaScript的这一奇异的“特征”,我们在函数内部定义变量时,请严格恪守“在函数内部起首说明一切变量”这一划定规矩。

  3. 闭包运用:封装私有变量

    function create_counter(initial) {
        var x = initial || 0;
        return {
            inc: function () {
                x += 1;
                return x;
            }
        }
    }
  4. 箭头函数
    箭头函数相当于匿名函数,而且简化了函数定义。箭头函数有两种花样,一种只包括一个表达式,连{ … }和return都省略掉了。另有一种能够包括多条语句,这时刻就不能省略{ … }和return
    返回对象:

    // SyntaxError:
    x => { foo: x }
    // ok:
    x => ({ foo: x })

    箭头函数完整修复了this的指向,箭头函数内部的this是词法作用域,由上下文肯定

  5. 扩大:装潢器

    如今假定我们想统计一下代码一共挪用了多少次parseInt(),能够把一切的挪用都找出来,然后手动加上count += 1,不过如许做太傻了。最好计划是用我们本身的函数替换掉默许的parseInt():

    var count = 0;
    var oldParseInt = parseInt; // 保留原函数
    
    window.parseInt = function () {
        count += 1;
        return oldParseInt.apply(null, arguments); // 挪用原函数
    };
    
    // 测试:
    parseInt('10');
    parseInt('20');
    parseInt('30');
    count; // 3

对象

  1. 须要恪守的划定规矩

    • 不要运用new Number()、new Boolean()、new String()建立包装对象;

    • parseInt()parseFloat()来转换恣意范例到number;

    • String()来转换恣意范例到string,或许直接挪用某个对象的toString()要领;

    • 一般没必要把恣意范例转换为boolean再推断,因为能够直接写if (myVar) {…};

    • typeof操纵符能够推断出number、boolean、string、function和undefined;

    • 推断Array要运用Array.isArray(arr)

    • 推断null请运用myVar === null

    • 推断某个全局变量是不是存在用typeof window.myVar === 'undefined'

    • 函数内部推断某个变量是不是存在用typeof myVar === 'undefined'

  2. 猎取时刻戳

    if (Date.now) {
        alert(Date.now()); // 老版本IE没有now()要领
    } else {
        alert(new Date().getTime());
    }
  3. JSON.stringify()

    • 花样化

      var xiaoming = {
          name: '小明',
          age: 14,
          gender: true,
          height: 1.65,
          grade: null,
          'middle-school': '\"W3C\" Middle School',
          skills: ['JavaScript', 'Java', 'Python', 'Lisp']
      };
      undefined
      JSON.stringify(xiaoming, null, '  ');
      "{
        "name": "小明",
        "age": 14,
        "gender": true,
        "height": 1.65,
        "grade": null,
        "middle-school": "\"W3C\" Middle School",
        "skills": [
          "JavaScript",
          "Java",
          "Python",
          "Lisp"
        ]
      }"
    • 挑选数据
      第二个参数用于掌握怎样挑选对象的键值,假如我们只想输出指定的属性,能够传入Array:

      JSON.stringify(xiaoming, ['name', 'height'], '  ');
      "{
        "name": "小明",
        "height": 1.65
      }"

      也能够传入函数举行处置惩罚

浏览器

  1. 猎取UA

    function whatBrowser() {  
        document.Browser.Name.value=navigator.appName;  
        document.Browser.Version.value=navigator.appVersion;  
        document.Browser.Code.value=navigator.appCodeName;  
        document.Browser.Agent.value=navigator.userAgent;  
    }

    请注重,navigator的信息能够很容易地被用户修正,所以JavaScript读取的值不一定是准确的

  2. cookie平安题目
    因为JavaScript能读取到页面的Cookie,而用户的登录信息一般也存在Cookie中,这就造成了庞大的平安 隐患。为了处理这个题目,服务器在设置Cookie时能够运用httpOnly,设定了httpOnly的Cookie将不能被JavaScript读取。这个行为由浏览器完成,主流浏览器均支撑httpOnly选项,IE从IE6 SP1最先支撑。
    为了确保平安,服务器端在设置Cookie时,应当一直对峙运用httpOnly。

  3. 按字符串递次从新排序DOM节点

    <!-- HTML构造 -->
    <ol id="test-list">
        <li class="lang">Scheme</li>
        <li class="lang">JavaScript</li>
        <li class="lang">Python</li>
        <li class="lang">Ruby</li>
        <li class="lang">Haskell</li>
    </ol>
    var ol = document.getElementById('test-list'),
        lis = [].slice.call(ol.children);
    lis.sort((a,b)=>  a.innerText.toUpperCase() > b.innerText.toUpperCase());
    lis.forEach(x=>{ol.appendChild(x)})
  4. children属性时刻都在变化
    当你遍历一个父节点的子节点并举行删除操纵时,要注重,children属性是一个只读属性,而且它在子节点变化时会及时更新。
    比方,关于以下HTML构造:

    <div id="parent">
        <p>First</p>
        <p>Second</p>
    </div>

    当我们用以下代码删除子节点时:

    var parent = document.getElementById('parent');
    parent.removeChild(parent.children[0]);
    parent.removeChild(parent.children[1]); // <-- 浏览器报错

    浏览器报错:parent.children[1]不是一个有用的节点。缘由就在于,当<p>First</p>节点被删除后,parent.children的节点数目已从2变为了1,索引[1]已不存在了。

  5. 扩大演习
    把与Web开辟手艺不相关的节点删掉

    <!-- HTML构造 -->
    <ul id="test-list">
        <li>JavaScript</li>
        <li>Swift</li>
        <li>HTML</li>
        <li>ANSI C</li>
        <li>CSS</li>
        <li>DirectX</li>
    </ul>
    var parent = document.getElementById('test-list');
    var children = [].slice.call(parent.children);  //Array.prototype.slice.call()
    children.forEach((element) => {
        for(var s of ['Swift', 'ANSI C', 'DirectX']){
            if(element.innerText == s){
                parent.removeChild(element);
            }
        }
    });

事宜

  1. 须要特别注重的是,下面这类写法是无效的:

    // 绑定事宜:
    a.click(function () {
        alert('hello!');
    });
    
    // 消除绑定:
    a.off('click', function () {
        alert('hello!');
    });

    这是因为两个匿名函数虽然长得如出一辙,然则它们是两个差别的函数对象,off('click', function () {...})没法移除已绑定的第一个匿名函数。
    为了完成移除结果,能够运用off('click')一次性移除已绑定的click事宜的一切处置惩罚函数。
    同理,无参数挪用off()一次性移除已绑定的一切范例的事宜处置惩罚函数。

  2. 事宜触发前提
    一个须要注重的题目是,事宜的触发老是由用户操纵激发的,然则,假如用JavaScript代码去修改,将不会触发change事宜
    有些时刻,我们愿望用代码触发change事宜,能够直接挪用无参数的change()要领来触发该事宜

    var input = $('#test-input');
    input.val('change it!');
    input.change(); // 触发change事宜

    input.change()相当于input.trigger('change'),它是trigger()要领的简写。

  3. 浏览器平安限定
    在浏览器中,有些JavaScript代码只要在用户触发下才实行,比方,window.open()函数:

    // 没法弹出新窗口,将被浏览器屏障:
    $(function () {
        window.open('/');
    });

    这些“敏感代码”只能由用户操纵来触发:

    var button1 = $('#testPopupButton1');
    var button2 = $('#testPopupButton2');
    
    function popupTestWindow() {
        window.open('/');
    }
    
    button1.click(function () {
        popupTestWindow();
    });
    
    button2.click(function () {
        // 不马上实行popupTestWindow(),100毫秒后实行:
        setTimeout(popupTestWindow, 100);
    });

    当用户点击button1时,click事宜被触发,因为popupTestWindow()在click事宜处置惩罚函数内实行,这是浏览器许可的,而button2的click事宜并未马上实行popupTestWindow(),耽误实行的popupTestWindow()将被浏览器阻拦。

Ajax

  1. open要领的第三个参数
    万万不要把第三个参数指定为false,不然浏览器将住手相应,直到AJAX要求完成。

  2. 跨域计划

    • flash插件,如今用的很少

    • 代理服务器,须要服务器端做分外开辟

    • jsonp,只支撑get要求

    • cors,经由过程http头的Access-Control-Allow-Origin考证

编写jquery插件准绳

  • $.fn绑定函数,完成插件的代码逻辑;

  • 插件函数末了要return this;以支撑链式挪用;

  • 插件函数要有默许值,绑定在$.fn.<pluginName>.defaults上;

  • 用户在挪用时可传入设定值以便掩盖默许值。

扩大jQuery对象的功用非常简朴,然则我们要遵照jQuery的准绳,编写的扩大要领能支撑链式挪用、具有默许值和过滤特定元素,使得扩大要领看上去和jQuery自身的要领没有什么区别。

此篇跳过了js中的面向对象,高阶函数,正则,原型等难点,下篇等我好好研究一下继承

参考资料

Javascript多维数组扁平化
廖雪峰先生的js教程

    原文作者:jasminecjc
    原文地址: https://segmentfault.com/a/1190000007073306
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞