瞭解JavaScript核心精髓(三)

1.js判斷對象是否存在屬性。javascript

    hasOwnProperty(‘property’)  判斷原型屬性是否存在。php

    "property" in o;  判斷原型屬性原型鏈屬性是否存在。java

2.js 對象比較     ajax

var obj1 = {
      "emailadr": "sroot@qq.com",
      "emailpas": "1000"
};

var obj2 = {
       "emailadr": "sroot@qq.com",
       "emailpas": "1000"
};

console.log(obj1==obj2)  // false ,比較對象的內存地址,不是內容

     最簡單的方法是直接轉成字符串,再進行比較。json

3.深拷貝與淺拷貝後端

     淺度拷貝,即複製一個引用類型的指針。跨域

     深度拷貝,即複製一個如出一轍完整引用類型。數組

     判斷淺度拷貝或深度拷貝依據比較兩個對象內存地址是否相等,相等就是淺度拷貝,不相等就是深度拷貝。 瀏覽器

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);
}
相關文章
相關標籤/搜索