您的位置:

首页 >

网页技巧 >

深入理解JavaScript系列(9) 根本没有“JSON对象”这回事! >

深入理解JavaScript系列(9) 根本没有“JSON对象”这回事!

2016-07-04 14:43:57

分类:网页技巧

前言 写这篇文章的目的是经常看到开发人员说:把字符串转化为JSON对象,把JSON对象转化成字符串等类似的话题,所以把之前收藏的一篇老外的文章整理翻译了一下,供大家讨论,如有错误,请大家指出,多谢。 正文 本文的主题是基于ECMAScript262-3来写的,2011年的262-5新规范增加了JSON对象,和我们平时所说的JSON有关系,但是不是同一个东西,文章最后一节会讲到新增加的JSON对象。 英文原文:http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/ 我想给大家澄清一下一个非常普遍的误解,我认为很多JavaScript开发人员都错误地把JavaScript对象字面量(Object Literals)称为JSON对象(JSON Objects),因为他的语法和JSON规范里描述的一样,但是该规范里也明确地说了JSON只是一个数据交换语言,只有我们将之用在string上下文的时候它才叫JSON。 序列化与反序列化 2个程序(或服务器、语言等)需要交互通信的时候,他们倾向于使用string字符串因为string在很多语言里解析的方式都差不多。复杂的数据结构经常需要用到,并且通过各种各样的中括号{},小括号(),叫括号<>和空格来组成,这个字符串仅仅是按照要求规范好的字符。 为此,我们为了描述这些复杂的数据结构作为一个string字符串,制定了标准的规则和语法。JSON只是其中一种语法,它可以在string上下文里描述对象,数组,字符串,数字,布尔型和null,然后通过程序间传输,并且反序列化成所需要的格式。YAML和XML(甚至request params)也是流行的数据交换格式,但是,我们喜欢JSON,谁叫我们是JavaScript开发人员呢! 字面量 引用Mozilla Developer Center里的几句话,供大家参考: 他们是固定的值,不是变量,让你从“字面上”理解脚本。 (Literals) 字符串字面量是由双引号(")或单引号(')包围起来的零个或多个字符组成的。(Strings Literals) 对象字面量是由大括号({})括起来的零个或多个对象的属性名-值对。(Object Literals) 何时是JSON,何时不是JSON? JSON是设计成描述数据交换格式的,他也有自己的语法,这个语法是JavaScript的一个子集。 { "prop": "val" } 这样的声明有可能是JavaScript对象字面量也有可能是JSON字符串,取决于什么上下文使用它,如果是用在string上下文(用单引号或双引号引住,或者从text文件读取)的话,那它就是JSON字符串,如果是用在对象字面量上下文中,那它就是对象字面量。 复制代码 代码如下: // 这是JSON字符串 var foo = '{ "prop": "val" }'; // 这是对象字面量 var bar = { "prop": "val" }; 而且要注意,JSON有非常严格的语法,在string上下文里{ "prop": "val" } 是个合法的JSON,但{ prop: "val" }和{ 'prop': 'val' }确实不合法的。所有属性名称和它的值都必须用双引号引住,不能使用单引号。另外,即便你用了转义以后的单引号也是不合法的,详细的语法规则可以到这里查看。 放到上下文里来看 大家伙可能嗤之以鼻:难道JavaScript代码不是一个大的字符串? 当然是,所有的JavaScript代码和HTML(可能还有其他东西)都是字符串,直到浏览器对他们进行解析。这时候.jf文件或者inline的JavaScript代码已经不是字符串了,而是被当成真正的JavaScript源代码了,就像页面里的innterHTML一样,这时候也不是字符串了,而是被解析成DOM结构了。 再次说一下,这取决于上下文,在string上下文里使用带有大括号的JavaScript对象,那它就是JSON字符串,而如果在对象字面量上下文里使用的话,那它就是对象字面量。 真正的JSON对象 开头已经提到,对象字面量不是JSON对象,但是有真正的JSON对象。但是两者完全不一样概念,在新版的浏览器里JSON对象已经被原生的内置对象了,目前有2个静态方法:JSON.parse用来将JSON字符串反序列化成对象,JSON.stringify用来将对象序列化成JSON字符串。老版本的浏览器不支持这个对象,但你可以通过json2.js来实现同样的功能。 如果还不理解,别担心,参考一下的例子就知道了: 复制代码 代码如下: // 这是JSON字符串,比如从AJAX获取字符串信息 var my_json_string = '{ "prop": "val" }'; // 将字符串反序列化成对象 var my_obj = JSON.parse( my_json_string ); alert( my_obj.prop == 'val' ); // 提示 true, 和想象的一样! // 将对象序列化成JSON字符串 var my_other_json_string = JSON.stringify( my_obj ); 另外,Paul Irish提到Douglas Crockford在JSON RFC里用到了“JSON object”,但是在那个上下文里,他的意思是“对象描述成JSON字符串”不是“对象字面量”。 更多资料 如果你想了解更多关于JSON的资料,下面的连接对你绝对有用:

js中鼠标事件主要有onclick,onmousedown,onmouseup,oncontextmenu,ondblclick,所有的这些事件都包含有一个事件对象event,当然在IE低版本下,event对象是挂在window底下的。这个我们另行讨论。1.通过html添加事件 <input type="button" click="alert(1)"/>2.通过DOM0级方式添加事件<input type="button" value="点击"/><script> var btn=document.getElementsByTagName('input')[0]; btn.onclick=function(){ alert(1);}</script>3.通过DOM2级方式添加事件事件监听主要接受三个参数,事件类型,事件需要执行的函数,是否冒泡,默认情况下是允许冒泡的document.addEventListener('click',function( ){ },true)以上是关于事件添加的三种方式,通过DOM0级方式添加事件有一个缺点就是当添加同一个事件是,后写的会把先写的给覆盖掉,但是通过DOM2级方式添加的相同事件是不会覆盖前面的事件的。同时,需要注意的是通过DOM2级添加的事件类型前面是没有‘on'的,接着就是如果要移除事件的话,DOM0级直接让事件为null就能清除事件,但是如果是DOM2级添加的函数是匿名函数,通过removeEventListener()方法是没办法移除的,因为两者指向的不是同一个函数,如果要移除,请记得使用有名函数。关于最后一个参数true是代表冒泡,false是代表捕获。/** 当触发onclick事件时,console.log(ev.which),鼠标左键的which值为1* 当触发oncontextmenue时,鼠标的右键值为3,不会触发onclick事件* 当mousewheel时,鼠标的中键键值为0* 当document.down时,可以根据按键的不同,从左到右鼠标键值依次为1,2,3* 在chrome底下,查看ev.wheelDelta,向上是120,向下是-120* 在FirFox底下,通过addEventListenner()来给鼠标添加滚轮事件,事件类型是DOMMouseScroll,查看是使用ev.detail* 向上是3,向下是-3*以上这篇关于js中的鼠标事件总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

插件截图:用途:点击链接或按钮时要确认是否继续当前操作。插件代码:复制代码 代码如下: (function($){ $.fn.confirmer = function(options){ var defaults = { msg:"Are you sure to delete it ?" } var options = $.extend(defaults, options); var control=$(this); $(control).click(function(){return confirm(options.msg);}); }; })(jQuery); 用法: 1.$(".delete").confirmer(); 2.$(".delete").confirmer({msg:'确认删除吗?'}); 示例: 复制代码 代码如下: <!DOCTYPE html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>jquery.confirmer.js</title>   <meta http-equiv="Content-Type" content="text/html; char set=utf-8" /> <script type="text/javascript" language="javascript" src="js/jquery.js"></script> <script type="text/javascript" language="javascript" src="js/jquery.confirmer.js"></script> <script type="text/javascript"> $().ready(function(){ $(".delete").confirmer(); //$(".delete").confirmer({msg:'确认删除吗?'}); }) </script> </head> <body> <button id="btnDelete" class="delete">删除</button> <a id="lnkDelete" class="delete" href="http:

复制代码 代码如下: function adjustIFramesHeightOnLoad(iframe) { var iframeHeight = Math.min(iframe.contentWindow.window.document.documentElement.scrollHeight, iframe.contentWindow.window.document.body.scrollHeight); $(iframe).height(iframeHeight); } 失败的测试就不说了,来直接的。 两个链接和iframe: 复制代码 代码如下: <li><a href="selfinfo.jsp" target="c-c-iframe" title="个人信息" >个人信息</a></li> <li><a href="modifypass.jsp" target="c-c-iframe" title="修改密码" >修改密码</a></li> <iframe src="init.jsp" id="c-c-iframe" name="c-c-iframe" width="500px;" frameborder="0" scrolling="no" marginwidth="0" marginheight="0"></iframe> js代码: 复制代码 代码如下: <script type="text/javascript"> <!-- $(function(){ $("#c-c-iframe").load(function(){ $(this).height($(this).contents().find("#content").height() + 40); }); }); --> </script> 这里的find("#content")是找出iframe内容文档中的id为content的高度(另外比如find("body")),并设置给iframe, 类似的还可以设置宽度,留给需要的朋友尝试吧。 这样就解决了iframe不会因为内容过大被挡住的问题(因为我设置了scrolling="no")。 PS:基本上我会优先考虑使用iframe来实现无刷新,兼容浏览器的后退按钮;而且使用iframe加载flash是很爽的,不用写什么js调用,object标签,还符合W3C标准。 2008年11月28日17:13:31 ,今天使用过程中根据实际情况进行了一下改良,代码如下: 复制代码 代码如下: <script type="text/javascript"> <!-- $(function(){ $("#workArea").load(function(){ var height = $(this).contents().find("#box").height() + 40; //这样给以一个最小高度 $(this).height( height < 400 ? 400 : height ); }); }); --> </script> 另发现使用find("body")不太好使,高度不准确。

而this的具体值则取决于其调用模式。 * 方法调用模式:this被绑定到该对象。 * 函数调用模式:this被绑定到全局对象,网页的情况下绑定到window * 构造器调用模式:this被绑定到新生成的对象。 * 事件处理调用模式分两种情况:参照 * this被绑定到全局对象 复制代码 代码如下: <script type="text/javascript"> function click_handler() { alert(this); // alerts the window object } </script> ... <button id='thebutton' onclick='click_handler()'>Click me!</button> * this被绑定到DOM对象 复制代码 代码如下: <script type="text/javascript"> function click_handler() { alert(this); // alerts the button DOM node } function addhandler() { document.getElementById('thebutton').onclick = click_handler; } window.onload = addhandler; </script> ... <button id='thebutton'>Click me!</button> 由于函数调用的上下文的变化导致了this的不确定性。为了更好的明确this上下文,可以使用call和apply两个方法来明确化this绑定的值。 call和apply的区别仅仅在于参数上的区别:call接受任意参数列表,apply接受一个参数数组对象。这也使得apply可以接受arguments作为其第二参数。 复制代码 代码如下: func.call(obj1,var1,var2,var3) func.apply(obj1, [var1,var2,var3]) func.apply(obj1, arguments) 但是call和apply方式都是立即执行的,如果需要后来使用的话,就不能满足条件,如下例,其中13行和14行无论是否使用call都无法得到我们需要的值(42)。 复制代码 代码如下: <script type="text/javascript"> function BigComputer(answer) { this.the_answer = answer; this.ask_question = function () { alert(this.the_answer); } } function addhandler() { var deep_thought = new BigComputer(42), the_button = document.getElementById('thebutton'); //the_button.onclick = deep_thought.ask_question; the_button.onclick = deep_thought.ask_question.call(deep_thought); } window.onload = addhandler; </script> 这个时候就是bind方法大显身手的时候(该方法已经在ECMA-262第五版已经加入),最早出现在Prototype框架中(未确认过)。bind和call,apply一样,也是变更函数执行的上下文,也即函数执行时this的值。不同的在于,它返回一个函数引用以供后续使用,其简单实现如下: 复制代码 代码如下: Function.prototype.bind = function(object) { var method = this; return function() { method.apply(object, arguments); } } 具体实现上利用闭包特性,返回来的函数引用在执行的时候,可以访问创建该函数引用时的method和object两个参数,而不是使用this,this在执行的时候会重新被绑定,而不是原来的method这个值。

焦点访谈

最新最热的文章

更多 >

COPYRIGHT (©) 2017 Copyright ©2017 5060网址大全 网站地图

联系我们

827570882

扫描二维码分享到微信