• 了解JavaScript核心精髓(三)


    1.js判断对象是否存在属性。

        hasOwnProperty(‘property’)  判断原型属性是否存在。

        "property" in Object 判断原型属性原型链属性是否存在。

    2.js 对象比较     

    var obj1 = {
          "emailadr": "sroot@qq.com",
          "emailpas": "1000"
    };
    
    var obj2 = {
           "emailadr": "sroot@qq.com",
           "emailpas": "1000"
    };
    
    console.log(obj1==obj2)  // false ,比较对象的内存地址,不是内容

         最简单的方法是直接转成字符串,再进行比较。

    3.深拷贝与浅拷贝

         浅度拷贝,即复制一个引用类型的指针。

    var a = 1;
    var b = a;
    console.log(b);

         深度拷贝,即复制一个一模一样完整引用类型。

    //ES5 方式一
    const newObj = JSON.parse(JSON.stringify(oldObj));
    
    //ES5 方式二
    function deepClone(obj) {
        let newObj = Array.isArray(obj) ? [] : {}
        if (obj && typeof obj === "object") {
            for (let key in obj) {
                if (obj.hasOwnProperty(key)) {
                    newObj[key] = (obj && typeof obj[key] === 'object') ? deepClone(obj[key]) : obj[key];
                }
            }
        } 
        return newObj
    }
    const newObj = deepClone(oldObj));
    
    //ES6
    const newObj = Object.assign([],oldObj);

           判断浅度拷贝或深度拷贝依据比较两个对象内存地址是否相等,相等就是浅度拷贝,不相等就是深度拷贝。 

    PS:引用类型指的是对象、数组、函数。

             值类型指的是数值、字符串、布尔型、null、undefined。 

    4.js访问对象属性

    //使用.来访问
    var myCar = new Object();
    myCar.make = "Ford";
    
    //使用[]来访问 
    myCar["make"] = "Ford";

    5.js对象继承

    //学生类
    function Student(name,age){
          this.name = name;
          this.age = age;
    }
    
    //小学生类
    function Pupil(name,age){
          this.stu=Student;
          this.stu(name,age);
    }
    
    var s = new Pupil('cww', 10)
    console.log(s.name)  //cww

    PS:可以多继承和重写,没有重载,如有同名函数,只执行最后的一个方法。

    6.js面向对象。

    非对象设计

    function popBox() {
        alert('弹出盒子')
    }
    popBOX()  //不知道是指哪个弹出盒子。
    优点:代码简练。
    缺点:语义化不明确,容易全局污染。
    对象设计
    var Top = {
        popBox: function() {
             alert('弹出盒子')
        }
    }
    Top.popBox()  // 顶部模块弹出盒子
    优点:有命名空间(实现模块化),可拓展(便于继承),避免函数重名,明确语义化。
    缺点:代码冗余。
     
    7.js 对象方法类型
       对象方法 (js对象需要new才能使用的方法)
    // 构造函数Person
    function Person() {
    this.walk = function() { alert('I can walk') } } var p1 = new Person() p1.walk()

        类方法  (js对象不需要new使用的方法)

    // 构造函数Person
    var Person = {
         walk: function() {
              alert('I can walk')
         }
    }
    
    //等价于
    //function Person() {}
    //Person.walk = function() {
    //    alert('I can walk')
    //}
    
    Person.walk()
        原型方法 (js对象继承拓展的方法,需要new才能使用的方法)
    // 构造函数Person
    function Person(name) {
        this.name = name
    }
    Person.prototype.sayName = function() {
        alert('my name is:' + this.name)
    }
    Person.prototype.age = 18
    var p1 = new Person('sroot') 
    p1.sayName()

    PS:原型方法与对象方法比较。

            使用原型方法更好,提高js使用内存效率,所有的new对象都共享方法。

            原型方法(实例方法)与类方法(静态方法)比较。

            静态方法在程序开始时生成内存。实例方法在程序运行中生成内存。

            静态方法常见于公用的方法,不需要依赖其他属性,不会被重写。实例方法常见于具体某个对象的方法。

    8.函数声明与函数表达式区别

    foo1(); //需要初始化
    function foo1(){}; //事先定义这个函数,不可以匿名。
    
    var foo2 =  function(){};//遇到才执行这个函数,可以匿名,函数可以内部调用。
    foo2();//必须在foo2函数表达式后面。

    9.js跨域问题(不同域名之间的js不能相互操作)

         只要是端口,协议,域名不同都算跨域。

        (1)使用jsonp。

                 通过script标签(script标签的src属性是没有跨域的限制的),引入其他域名下的带参数函数,从而读取跨域数据。(仅支持get请求)           

    <script type="text/javascript">
      //返回函数一定要事先声明,否则jsonp请求返回的函数是Undefined
      function callbackFunction(result) {
        console.log(result)
      }
      // 提供jsonp服务的url地址
      // url后面参数可有可无,建议设置参数,有利于可以动态获取返回数据,告诉后端“我需要一个callbackFunction函数代码”,函数名不是固定的。
      var url = 'http://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction'
      var script = document.createElement('script')
      script.setAttribute('src', url)
      document.getElementsByTagName('head')[0].appendChild(script)
    </script>
    <!-- 不建议写死script标签的src -->
    <!-- <script type="text/javascript" src="http://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction"></script> -->

       (2)使用iframe。

                 创建一个iframe,修改domain,读取iframe里面的数据。

       (3)服务端设置跨域请求头。

       (4)使用浏览器代理插件。(Allow-Control-Allow-Origin: *插件)

    PS:jsonp安全问题:建议请求验证的refer字段或token,否则会出现CSRF攻击漏洞。

    10.js判断条件优化

    (1)把最常出现的结果排在前面

    // var value = xxx
    if (value === 4) {
    
    } else if (value === 3) {
    
    } else if (value === 1) {
    
    } else if (value === 2) {
    
    } else if (value === 0) {
            
    }

    (2)拆分条件

    // var value = xxx
    if (value <= 4) {
         if (value > 2) {
              if (value === 3) {
    
              } else if (value === 4) {
    
              }
          } else {
              if (value === 0) {
    
              } else if (value === 1) {
    
              } else if (value === 2) {
    
              }
          }
    }

    (3)switch语句

    //var value = xxx
    switch(value){
       case 1:
      
           break;
       case 2:
      
           break;
       default:
           
    }

    PS:default关键字后面无需加break关键字。

            参数是固定值采用switch语句。

            参数是范围值采用if语句。

    (4)数据查询

    //var value =xxx
    
    var arrRes = [0,1,2,3,4]
    
    var results = arrRes[value] 

    11.js使用别名

    function $(id) {
        return document.getElementById(id)
    }
    
    var titleCss = $('title').style
    titleCss.color = 'red'

    节省代码,便于书写。

    12:js遍历语句

    //for遍历(适用于数组对象)
    for (var i = 1; 1 < 5; i++) {
      console.log(i);
    }
    
    //for...in遍历(适用于数组对象)
    var arrData1=[{name:"foo1"},{name:"foo2"}]
    
    for (var key in arrData1) {
      console.log(arrData1[key].name)
    }
    
    //Array.prototype.map()遍历(适用于数组对象)
    var arrData2 = [10, 50, 100];
    arrData2.map(x => console.log(x));

    PS:性能高到低  for > map > for..in 

             for...in遍历  > Object.keys遍历

             尽可能使用 for循环,不要使用增强的for循环。

    13.js阻止页面内部iframe运行。

    if (navigator.appName == 'Microsoft Internet Explorer') {
            window.frames.document.execCommand('Stop')
       } else {
            window.frames.stop()
    }

     14.js禁止外部iframe嵌套

    if (window.top != window && document.referrer) {
       var a = document.createElement('a')
       a.href = document.referrer
       var host = a.hostname
       
       var endsWith = function(str, suffix) {
             return str.indexOf(suffix, str.length - suffix.length) !== -1
       }
    
       if (!endsWith(host, '.test.com') || !endsWith(host, '.test2.com')) {
              top.location.href = 'http://www.test.com'
       }
    }

     15. 捕获异常

    try{ 
       ...
    }catch(e){
       var msg = (e.message) ? e.message : e.description;
       alert(msg);
    }
  • 相关阅读:
    jenkins实现git自动拉取代码时替换配置文件
    【一些小常识】Linux文件目录的通配符用法/*
    mysql使用——sql实现随机取一条数据
    jmeter使用问题——数据库无法连接
    【测试点】微信小程序的常见测试点
    分位数介绍
    elk开源版本支持的功能
    kali下的webshell工具-Weevely
    kali中的webshell工具--webacoo
    sql报错注入:extractvalue、updatexml报错原理
  • 原文地址:https://www.cnblogs.com/Sroot/p/10064607.html
Copyright © 2020-2023  润新知