了解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);
}
相关文章
相关标签/搜索