JS高级程序设计3

PS:有一小部分写在了 JS 2017了

JSON

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
IE8支持 JSON.stringify()
<script>
  var book = {
    "title":"js",
    "author":"kang",
    "edition":3
  }
  // 1.过滤结果
  var res =JSON.stringify(book,['title','author'])
  console.log(res);
  console.log(JSON.parse(res).title);
  // 2 自定义数据
  var res2=JSON.stringify(book,function (key, val) {
    switch (key){
      case "title":
        return val+ ' es6'
      case "author":
        return 'jia'
      case "edition":
        return undefined
      default:
        return val
    }
  })
  console.log(res2);
  // 3 格式化
  var res3=JSON.stringify(book,['title'],2)  // 第3个值是格式化属性,可以为数字,代码缩进的空格数,如果是字符串,则是用字符串代替空格来缩进
  // var res3=JSON.stringify(book,['title'],'---')
  console.log(res3);
  // 4 toJSON   不实用
  var book2 = {
    "title":"es5 es6",
    "year":2017,
    toJSON:function () {
      return this.title
    }
  }
  console.log(book2.toJSON());  // es5 es6
</script>
</body>
</html>
View Code

 跨域

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
IE8通过XDomainRequest对象支持CORS跨域,21.4.5有原生的跨域封装,不知有没有用     JQ没封装
【跨域1】: img标签
一个网页可以从任意网页中加载图像,没有跨域的概念
<script>
  var img = new Image();
  img.src='http://xxxxxx'
  img.onload=function () {
    // ... 缺点是得不到任何具体的数据,用于在线广告跟踪浏览量,检测是否接收到而已
  }
  img.onerror=function () {
    // ...
  }
</script>
【跨域2】 jsonp
jsonp是通过动态script元素来使用的, JQ有实现
跨域请求,可能其他域不安全,有恶意代码
通过onerror来判断
<script>
  function handleResponse() {
    // ...
  }
  var script = document.createElement('script')
  script.src='http://xxx?callback=handleResponse'  // callback 回调函数
  document.body.insertBefore(script,document.body.firstChild)
</script>
【跨域3】 comet ie不支持
【跨域4】 web sockets ie不支持
</body>
</html>
View Code

 

什么是跨域?
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。

所谓同源是指,域名,协议,端口均相同,不明白没关系,举个栗子:

http://www.123.com/index.html 调用 http://www.123.com/server.PHP (非跨域)

http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)

http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)

http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)

http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

 //作用域安全的构造函数

  // 多人在同一页面写js代码,推荐使用作用域安全的构造函数,防止乱来
  function Person(name, age) {
    this.name = name;
    this.age = age;
  }
  var p = new Person('kang', 12)
  console.log(p.name);
  // 乱来
  var p2 = Person('jia', 11)
  console.log(window.name); // jia 乱来
  // 作用域安全的构造函数,
  function Student(hobby, age) {
    if (this instanceof Student) {
      this.hobby = hobby;
      this.age = age;
    } else {
      return new Student(hobby, age)
    }
  }
  var s1 = Student('play', 3)
  console.log(window.hobby); // undefined  防止乱来
  console.log(s1.hobby);
View Code
// 防篡改对象 preventExtensions   密封对象seal   冻结对象freeze
  // 防篡改对象 preventExtensions
  var f1 = {name: 'xx'}
  Object.preventExtensions(f1); // es5
  f1.age = 22;
  console.log(f1.age);  // undefiend
  delete f1.name;
  console.log(f1.name);  // 属性被删除
  // 密封对象  seal
  var f2 = {name: 'xx'}
  Object.seal(f2); // es5
  f2.age = 22;
  console.log(f2.age);  // undefiend
  delete f2.name;
  console.log(f2.name); // xx  对象密封后,删除不了对象属性
  // 冻结对象  freeze 不能修改原有属性值
  var f3 = {name: 'xx'}
  Object.freeze(f3); // es5
  f3.name = 22
  console.log(f3.name);
View Code
第22章 22.1高级函数
安全的类型检测
惰性载入函数 22.1.3 P620页 处理多个 if else
函数绑定
函数柯里化
脚本长时间运行的原因之一是有大量处理的for循环,可用定时器切割成小任务 第22章 22.3.2
操作DOM比起非DOM交互需要更多的内存和CPU时间,当使用 onresize调整窗口大小事件时,事件会连续触发,可用定时器
限制100ms后才调用某函数,如果 100ms内调用函数20次,则函数只会被调用一次(定时器会把重复的请求给忽略掉,当上一次调用未执行时,新的请求会被忽略)
第22章 22.3高级定时器
// 断网 online offline    navigator.onLine()
window.addEventListener('online', function () {})
// sessionStorage localStorage ie8+
js规范
<script>
  // js规范
  /*
   *   变量名为名词 ,car
   * 函数名为动词, getCar()  isPhone()
   * 变量名和函数名不用担心长度,可压缩
   * 变量初始化一:
   * var found = false    // 表示布尔型
   * var person = null;   // 表示对象
   * 变量初始化二:
   * var bFound;  // 布尔型'b'   对象'o'  字符串's'  'i'整数 ’f'浮点数
   * var iCount; //  整数
   * var oPerson; //对象
   * var sName;  // 字符串
   * */
  // html与js分离
  /*
   *  减少用js追加html,可在html中直接显示html,再隐藏
   * */
  //  应用逻辑和事件处理分开成两个函数
  function validate(value) {
    value = 5 * parseInt(value)
    if (value > 10) {
      document.getElementById('error-msg').style.display = 'block'
    }
  }
  function handleKeyPress(event) {
    if (event.keyCode == 13) {
      validate(event)  // 把逻辑代码独立出来
    }
  }
  // 只为自己创建的对象 var Index = function(){} 添加方法,不为  Array、document等原生对象添加方法
  // 减少全局变量,改成对象的形式
  var name = 'kang';
  function getName() {  // 两个全局变量 name 和 getName
    return name;
  }
  var MyName = {    // 对象写法
    name: 'kang',
    getName: function () {
      return name;
    }
  }
  // 命名空间
  var Person = {}
  Person.kang = {}  // kang就是命名空间
  Person.kang.test1 = function () {

  }
  // 减少null 比较
  function sortArray(val) {
//    if(value !=null){
    if (val instanceof Array) {  // 代替 null 判断  还可以用  typeof
      val.sort(compare)
    }
  }
  // 常量处理  重复值、用户界面字符串、url 、 任意可能会更改的值都要处理成常量,方便修改
  var Constants = {
    INVALID_VALUE_MSG:'invalid value',
    INVALID_VALUE_URL:'/home.html'
  }
  function validate2(val) {
    if(!val){
      alert(Constants.INVALID_VALUE_MSG)
      location.href=Constants.INVALID_VALUE_URL
    }
  }
  // 避免全局查找
  function updateUI() {
    var doc = document;  // 把 document 存起来
    var imgs = doc.getElementsByTagName('img')
    for(var i=0,len=imgs.length;i<len;i++){
      imgs[i].title=doc.title + ' image' + i;
    }
    var msg = doc.getElementById('msg')
    msg.innerHTML = 'update ok'
  }
  // 属性的查找,
  /*
  * 常量、数组查找最快,只有O(1), 执行时间恒定
  * for循环 O(n),跟元素数量有关
  *  window.location.href.indexOf('?');   O(3)  查找3次   一个点表示一次
  *
  * */
  var url = window.location.href;
  var query = url.substring(url.indexOf('?'))   // O(4)
  var query2 = window.location.href.substring(window.location.href.indexOf('?'))  // O(6)

  var value=[5,10];
  var sum = value[0]+value[1];  // O(1)
  var values={first:5,second:10}
  var sums = values.first + values.second;  // O(2)
  // for循环减值迭代 如果顺序不影响的话
  for(var i =value.length-1;i>=0;i--){
//    ...
  }
  // 使用 do-while 比for运行快,不想用
  // 展开循环
  /*
  * 当循环的次数是确定的,消除循环并使用多次函数调用比 for循环快
  * process(value[0]);
  * process(value[1]);
  * process(value[2]);
  * */
  /* 原生方法快  使用原生js方法而不是自己的js, 原生js是c/c++写出来的,比js快
  * switch比 if-else 快,还可以把 case 按常用顺序排列
  * 位运算符比任何布尔运算或算数运算快, 取模、逻辑与和逻辑或 都可以用位运算符来处理
  * */
  /* 最小化语句数
  * 多个变量声明
  * var a =1,b=2,c=3;  // 推荐
  * var a=1;
  * var b=2;
  * var c=3;
  *
   var name = value[i];
  *  i++;
  *  简化为  var  name = value[i++]
  *
  * */
</script>

 

posted @ 2017-08-17 17:57  gyz418  阅读(192)  评论(0)    收藏  举报