0 总结
本书的JS
1.1 执行js代码
java:alert(‘执行js’);//一般放在超链接中,用户点击即执行,
1.2 变量赋值
var a= 1;//显式a= 1; //隐式
1.3 全局变量与局部变量
...var scope = "全局变量"; functiontest(){ alert(scope); // undefiend var scope = "局部变量"; alert(scope); // 局部变量 }
因为全局变量被局部变量覆盖了.虽然局部变量的scope还没赋值,但是已经在方法里”占”上位置了.
但如果把局部变量的var删了,就会先输出全局变量后输出局部变量,因为没有var在方法里给局部变量”占”位置;
1.4 浮点数
vara = .333varb = a * 5; alert(b);
得出的结果是 1.66499999999999999
所以在js中判断浮点数是否相等 建议判断两者的差值是否小于一个足够的数(例如0.0000000000001)
1.5 字符串
js中没有字符类型变量 “”与’‘一致
vars = "abcdefg"//b = "def"b = s.slice( 3, - 1);
1.6 字符串的正则表达式方法中
1.7 undefined和null
null== undefined//truenull=== undefined//false
undefined 是没设值
null则是设定了为null值
1.8 运算符
//逗号运算符 取最右返回值a = (b = 5, c = 7, d = 56) //a =56a = void(b = 5, c = 7, d = 56) //a = undefined
1.9 typeof和instanceof
typeof 用来获得 实例类型 :
typeof( "123"); //string
instanceof 判断变量是否为某类的实例
vara = [ 4, 5]; alert(a instanceofArray); //true
1.10 语句
抛出异常
thrownewError( "用户自定义异常"); //一般用于终止程序和返回错误提示是个不错的选择;try{ } catch(e){ alert(e.message); // "用户自定义异常"}
for in
//这回输出浏览器的所有属性,做浏览器兼容之前可以考虑看看.for( prop_name innavigator){ document.wrti(prop_name + " : "+ navigator[propname]); }
跳出命名for
outer: for( ...){ for( ...){ ...continue outer; } }
1.11 函数
js 允许先调用函数 再定义函数
1.11.1 定义匿名函数
varshow_name = function(name){alert(name); } show_name( "K"); //K
这样的好处是什么,如果直接定义function 它实际上也是创建了一个对象
1.11.2 函数既对象
varhello = function(){...}; hello instanceofFunction//true;hello instanceofObject//true;alert(heelo) //输出函数源代码
1.11.3 调用函数方式的不同
1.11.4 this关键字.
1.11.5 函数中的变量有三种
functionPerson(){//局部变量 只能在函数里访问varid ; //实例属性 通过对象.访问this.age ; //类属性 通过Patient.name访问 与static类似Person.name ; }
1.11.6 js是一种动态语言,能随时给对象增加属性和方法
functionStudent(){}; varstudent = newStudent(); //动态增加name属性student.name = 'K'; alert(sutdent.name) //KStudent.age = 22; alert(Student.age); //22 类属性也是可以动态添加的
1.11.7 调用函数的三种方式
1. 直接调用
windows .alert() ;// oralert() ;
作用:动态地传入一个函数引用
call()调用函数语法为:函数引用.call(调用者,参数1,参数2...)
直接调用函数语法为:调用者.函数(参数1,参数2 ...) = 函数.call(调用者,参数1,参数2 ...)
1.11.8 函数的独立性
在函数A中可以定义函数B,但是函数B还是独立于函数A
functionPerson(name){this.name = name; this.info = function(){alert( this.name); } } varperson = newPerson( 'K'); person.info(); //Kvarname = 'K_window'; //由于window为调用者 ,this.name访问的是window.namep.info.call(window); //K_window
来爽一发猫学狗叫?.
functionDog(name,bark){this.name = name; this.bark = bark; this.info = function(){alert( this.name + " "+ this.bark); } } functionCat(name){this.name =name; } vardog = newDog( "K", "汪汪!"); varcat = newCat( "K_2"); dog.info.call(cat); //K_2 undefined
1.11.9 参数传递方式
和JAVA一样 都是值传递拉~.
基本类型
functionchange(arg){arg = 10; alert(arg); } varx = 5; alert(x); //5change(x); //10alert(x); //5
复合类型
functionchange(person){person.age = 10; alert(person.age); person = null; } varperson = {age : 5}; alert(person.age); //5change(person); //10alert(person.age); // 10alert(person); // []object Object]
复合类型的传递为值传递,原person和参数person指向同一java对象,所以当改变age的时候,是在改变java对象的age,但是参数person赋值为null,原person并无改变.
1.11.10 空参数
functiontext(person){alert( typeofparson); } text(); //undefined
所以对于弱类型,方法重载是无作用的,因为js会把空参数当做undefined传递进去;
同名函数,后面出现的会覆盖前面的,无论参数个数是多少.
1.11.11 对象和关联数组
java和Map有点类似,当key为对象,value为函数,该该函数就是对象的方法,当key为对象,value为基本类型,则该基本类型为对象的属性.(以上为便于理解,切勿细琢)所以访问属性时,可以obj.propName也可以obj[propName].
但有时候我们只能用obj[propName],因为.propName不能把propName当做变量处理,而是把他当成’propName’字符串
functionPerson(name){this.name =name; this.info = function(){alert(K); } } varperson = newPerson( "K"); //遍历person属性for(propName inperson){ alert(p[propName]); //alet K info源代码 假如此处用p.propName则undefined,因为Person无'propName'变量.}
1.11.12 继承和prototype
在一个类(函数)中定义一个函数会导致
解决方案:prototype
增加了prototype属性的类可视为继承了原先的类(伪继承)
functionPerson(){ ...} var person = new Person(); //person.wark(); 程序报错wark不存在 Person.prototype.wark = function(){ ...} person.wark(); //ok
在prototype之前实例化的类会具有wark方法吗? 有的,因为prototype这样并不会产生一个新的类,而是直接动态的往Person里加函数.
判断某方法是否继承了该对象
该对象.prototype[ '某方法'] != undefined; vartest = new该对象(); test.某方法 != undefined;
1.12 创建对象三种方式
//(单身汪别说我不教你)
DOM操作其实JQuery已经做得很好了,这里简单补充一下原生JS的知识
HTML文档中只有一个根节点
2.1 访问HTML元素
2.2 增加HTML函数
2.3 添加节点
2.4 删除节点
2.5 window对象
2.6 navigator和地理位置
navigator汉堡浏览器所有信息,遍历循环获取信息
for( varpropName inwindow.navigator){ alert(propName + ":"+ window.navigator[propName]); }
HTML5新增geolocation属性
Geolocation提供的方法
1. getCurrentPosition(onSuccess,,options)
2. int watchCurrentPostion(OnSuccess,,options),周期性调用getCurrentPosition,返回的int代表这个”监听器”的ID,用来clearWatch(watchID)取消监听
3. clearWatch(watchID),用于取消watchCurrentPosition
上面的前两个方法的options参数是一个对象,可包含3个变量
例子:
2.7 HTML5新增浏览器分析
实现该功能主要通过performance对象
其中的(PerformanceTiming)timing属性包含加载时间相关的属性
另外(PerformanceNavigation)navigation,主要属性有
type :
TYPE_NAVIGATE(数值为0): 超链接/输入urlTYPE_RELOAD(1): 重新加载方式,diaoyonglocation.reload()等TYPE_BACK_FORWARD(2): 通过浏览器的前进方式TYPE_RESERVED(255): 未知方式
3 事件处理机制
3.1 常见事件
3.2 事件处理和this
p.info = function(){alert( this.name); } document.getElementById( "bt").onclick = p.info //this指向'bt'控件document.getElementById( "bt").onclick = newfunction(){p.info();} //this总是指向p
注意表单设置id为x和name为y时候,相当于表单创建了x属性和y属性,所以id和name不能是关键字submit等
3.3 DOM
创建监听事件
objectTarget.addEventListener(“eventType”,handler,capture),第一个参数表示绑定的事件,如click、keypress之类的,第二个制定绑定的函数,第3个位boolean,true表示监听捕获阶段,false表示监听冒泡阶段
objectTarget.removeEventListener(“eventType”,handler,captureFlag): 删除绑定事件
捕获状态阶段的绑定事件先执行,事件冒泡状态阶段的绑定事件后执行. 捕获状态阶段从外往内触发,事件冒泡状态阶段从内往外触发.
绑定例子
vargot_click = function ( event){ for( event_one inevent){ alert(event_one + " : "+ event[event_one]); } } document.getElementByID( "test").addEventListener( "cilck",got_click, true);
阻止事件传播
event.stopPropagation();
取消事件的默认行为,如跳转页面等,但不会阻止事件传播.
event.preventDefault();
3.3.1转发事件
DOM提供了dispathEvent方法用于事件转发,该方法属于Node
target.dispathEvent(Event event),将event转发到target上
DOM的dispath()必须转发人工合成的Event事件
document.createEvent(String type),tpy参数用于指定事件类型,eg:普通事件Events,UI事件UIEvents,鼠标事件:MouseEvents
初始化事件
initEvent(具体参数 ...) initUIEvent(具体参数 ...) intMouseEvent(具体参数 ...) //例子 <input id= "bt1"> <input id= "bt2"> ...var rd = function(evt){ alert( "事件冒泡阶段: "+ evt.currentTarget.value + "被点击了"); var e =document.createEvent( "Evnets"); e.initEvent( "click",true,false);//true表示是否支持冒泡,false表示是否有默认行为 document.getElementById( "bn2").dispathEvent(e); } var go_click = function(evt){ alert( "事件冒泡阶段: "+ evt.currentTarget.value); } document.getElementById( "bn1").addEventListener( "click",rd,false); document.getElementById( "bn2").addEventListener( "click",go_click,false);; //点解按钮一结果 alert(事件冒泡阶段: 按钮一被点击了); alert(事件冒泡阶段:按钮 2); 4 本地存储与离线应用
4.1 Web Storage
使用理由之一Cookie的局限性:
Web Storage包含在window对象中
当value为对象时,建议用JSON存储
4.2 构建离线应用
启动应用后,页面可刷新(即使离线状态),并使用离线时候的资源
4.2.1 判断在线状态
navigator.onLine属性: true表示在线
online/offline事件: 当在线/离线状态切换时,body上的online/offine事件会被触发,沿着document.body、document和window冒泡
window.addEventListener( "offline", function(){alert( "离线状态") }, true); if(navigator.onLine){ alert( "在线"); }
4.2.2 applicationCache对象
js可通过applicationCache控制离线缓存.
status属性:
常用方法
4.2.3 离线应用的事件与监听
访问html页面过程
当用户再访问index.html时,前面1~5完全相同,接下来检测mainfest文件是否有改变.
worker中无法使用DOM、alert等与界面有关的操作.
使用理由:防止js阻塞主线程的js运行
WorkerAPI
worker.js代码
网页代码
<input name= "start"...> <input name= "end"...> <input type=button inclick= "cal();"...> ...var car = function(){ var start = parseInt(document.getElementById( "start").value); var end = parseInt(document.getElementById( "end").value); //创建线程 var cal = new Worker( "worker.js"); var data ={ "start": srart, "end": end }; //发送数据 cal.postMessage(JSON.stringify(data)); cal.onmessage = function(evnet){ alert(event); } }
并行的两条Worker不能互相通信,但Wroker可嵌套.
6 客户端通信
WebSocket: 服务器主动推送信息/客户端实时推送数据到服务器
6.1 跨文档通信
window对象新增方法
event中的属性:
html想发送要做
html想接收要做
跨文档消息传递
结果:
alert(接收到消息拉!传输消息);
alert(回传消息);
注意!一定要判断发送方的域名!!!!!一定要判断发送方的域名!!!!!一定要判断发送方的域名!!!!!
6.2 WebSocket与服务器通信
以前方案:
WebSocket方法
WebSocket监听事件
WebSocket属性
实现客户端多人聊天,JAVA为例
客户端代码:
varweb_socket = newWebSocket( "ws://域名:端口"); web_socket.onopen = function(){web_socket.onmessage = function(event){document.getElementById( 'show').innerHTML += event.data + "</br>"} }; varsendMsg = function(val){varinputElement = document.getElementByID( 'msg'); webSocket.send(inputElement.value); inputElement.value= ""; } ...
服务端代码
<article class= "post"style= "margin: 0px; padding: 30px 0px; border-bottom: 1px solid rgb(221, 221, 221); border-top: 1px solid rgb(255, 255, 255); position: relative; color: rgb(102, 102, 102); font-family: HelveticaNeue-Light, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(238, 238, 238);"> import java.io.*; import java.net.*; import java.nio.charset.Charset; import java.security.MessageDigest; import java.util.regex.*; import java.util.*; import sun.misc.BASE64Encoder; publicclassChatServer { // 记录所有的客户端SoccketpublicstaticList<Socket> clientSockets = newArrayList<Socket>(); publicChatServer()throws IOException { // 创建ServerSocket,准备接受客户端连接ServerSocket ss = newServerSocket( 30000); while( true) { // 接收到客户端连接Socket socket = ss.accept(); // 将客户端Socket添加到clientSockets集合中clientSockets.add(socket); // 启动线程newServerThread(socket).start(); } } publicstaticvoidmain(String[] args) throws Exception{ newChatServer(); } } class ServerThread extends Thread { privateSocket socket; publicServerThread(Socket socket) { this.socket = socket; } publicvoidrun() { try{ // 得到Socket对应的输入流InputStream in= socket.getInputStream(); // 得到Socket对应的输出流OutputStream out= socket.getOutputStream(); byte[] buff = newbyte[ 1024]; String req = ""; // 读取数据,此时建立与WebSocket的"握手"。intcount = in.read(buff); // 如果读取的数据长度大于0if(count > 0) { // 将读取的数据转化为字符串req = newString(buff , 0, count); System. out.println( "握手请求:"+ req); // 获取WebSocket的keyString secKey = getSecWebSocketKey(req); System. out.println( "secKey = "+ secKey); String response = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: "+ "websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "+ getSecWebSocketAccept(secKey) + "\r\n\r\n"; System. out.println( "secAccept = "+ getSecWebSocketAccept(secKey)); out.write(response.getBytes()); } inthasRead = 0; // 不断读取WebSocket发送过来的数据while((hasRead = in.read(buff)) > 0){ System. out.println( "接收的字节数:"+ hasRead); /* 因为WebSocket发送过来的数据遵循了一定的协议格式, 其中第3个〜第6个字节是数据掩码。 从第7个字节开始才是真正的有效数据。 因此程序使用第3个〜第6个字节对后面的数据进行了处理 */for( inti = 0; i < hasRead - 6; i++ ){ buff[i + 6] = ( byte) (buff[i % 4+ 2] ^ buff[i + 6]); } // 获得从浏览器发送过来的数据String pushMsg = newString(buff , 6, hasRead - 6, "UTF-8"); // 遍历Socket集合,依次向每个Socket发送数据for(Iterator<Socket> it = ChatServer.clientSockets.iterator() ; it.hasNext() ;) { try{ Socket s = it.next(); // 发送数据时,第一个字节必须与读到的第一个字节相同byte[] pushHead = newbyte[ 2]; pushHead[ 0] = buff[ 0]; // 发送数据时,第二个字节记录发送数据的长度pushHead[ 1] = ( byte) pushMsg.getBytes( "UTF-8").length; // 发送前两个字节s.getOutputStream().write(pushHead); // 发送有效数据s.getOutputStream().write(pushMsg.getBytes( "UTF-8")); } catch(SocketException ex) { // 如果捕捉到异常,表明该Socket已经关闭// 将该Socket从Socket集合中删除it.remove(); } } } } catch(Exception e) { e.printStackTrace(); } finally{ try{ // 关闭Socketsocket.close(); } catch(IOException ex) { ex.printStackTrace(); } } } // 获取WebSocket请求的SecKeyprivateString getSecWebSocketKey(String req) { //构建正则表达式,获取Sec-WebSocket-Key: 后面的内容Pattern p = Pattern.compile( "^(Sec-WebSocket-Key:).+", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); Matcher m = p.matcher(req); if(m.find()) { // 提取Sec-WebSocket-KeyString foundstring = m. group(); returnfoundstring.split( ":")[ 1].trim(); } else{ returnnull; } } // 根据WebSocket请求的SecKey计算SecAcceptprivateString getSecWebSocketAccept(String key) throws Exception { String guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; key += guid; MessageDigest md = MessageDigest.getInstance( "SHA-1"); md.update(key.getBytes( "ISO-8859-1") , 0, key.length()); byte[] sha1Hash = md.digest(); BASE64Encoder encoder = newBASE64Encoder(); returnencoder.encode(sha1Hash); } } [java](http: //mzkmzk.github.io/blog/categories/java/)</article> <a class= "addthis_button_facebook_like"fb:like:layout= "button_count"style= "margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: rgb(37, 143, 184);"></a><a class= "addthis_button_tweet"style= "margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: rgb(37, 143, 184);"></a>
【我有一个前端学习交流QQ群:328058344 如果你在学习前端的过程中遇到什么问题,欢迎来我的QQ群提问,群里每天还会更新一些学习资源。禁止闲聊,非喜勿进。】