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>
跨域
<!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>
什么是跨域?
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对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);
// 防篡改对象 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);
第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>

浙公网安备 33010602011771号