- 浏览: 66622 次
- 性别:
- 来自: 杭州
最新评论
-
meimei_123abc:
你好,可以把这个完整的代码给我发一个学习下吗,刚开始接触这一块 ...
在JNI中调用本地带结构体参数的函数 -
yangdong:
sorry,之后一直没再碰过 JNI,没法再写了。
在JNI中调用本地带结构体参数的函数 -
ihopethatwell:
楼主,能写一个传递数组的结构体?
在JNI中调用本地带结构体参数的函数 -
yangdong:
谢谢。我只是追求形似,所以找不到对应的写法。
Stream in Clojure -
jamesqiu:
Clojure的lazy-cat和Scala的Stream实现 ...
Stream in Clojure
准备工作
为了演示或者您试验,请先准备好下面的 HTML 模板。
这个页面包含一个两列的表格。"Insert A Row" 这个按钮意在向此表中添加一行。"Remove A Row"意在从此表中删除一行。在文本框中指定要删除的行号(从一开始索引)。
第一种,基于单个对象
这种方法被称为块模式(Module Pattern)。最后的“()”会导致那个匿名函数立即执行,从而返回 return 块的对象。这个返回的对象被赋给了 tableObj。其中,count 为 tableObj 的私有成员变量,validateIndex() 函数为其私有成员函数。
为了看看效果,将上面的代码放在 <script> 标签之中。然后为“Insert A Row”按钮添加 onclick="insertARow()",为“Remove A Row”按钮添加 onclick="removeARow()"。最后,在 <script> 标签中再加入下面的两个函数,
这样,按钮的事件响应函数就添加完成了。现在您打开页面,应该就可以试验一下效果了。这种方法的优点是短平快,缺点是复用性较差。当然,这里指的不是 copy-paste 式的复用
假设有这样一个用例,还是这个页面,现在我需要再添加一个结构一样的表。难道要我们把上面的代码复制一遍吗?当然不。如果能支持以 new 的方法创建的话是最理想的。下面将介绍的方法基于类型,即构造函数。它是可以支持以 new 的方式创建对象的。
第二种,基于类型
这样的模式目前我还不知道是否有正式的名称。不过就目前我所知道的,网上各位作者仍然把类似这种基于类型的方法称为块模式。我认为,上面的模式就实现的功能来说是最优秀的。因为它能实现私有成员、私有静态、公有成员及公有静态。我将其称为类模式(Class Pattern)。
注意,公有成员函数 addRow() 和 removeRow() 在代码中使用了一个私有成员变量 tbodyId。而只有 TableClass 的构造函数带一个 tbodyId 的参数。就是这个 tbodyId 充当了私有成员变量。如果您觉得这样不好看,也可以在构造函数中加上这样一句话,
然后把那两处引用 tbodyId 的地方改成 _tbodyId。看您的喜好了。
将第一个例子改造,添加一个结构相同的表。首先添加 HTML,
然后初始化两个表对象,
最后改造按钮的事件响应函数,
OK。现在如果您点击“Insert A Row”应该可以看到两列内容相反但结构一致的表了。为了验证我们的公共静态成员 instances 是否有效,创建一个单独的按钮,
点击“Count table instances”,结果会显示“2”。
题外话,命名空间
为了避免全局名字污染,通常我们写的控件都会放一个全局名称之下。像 YUI 的 YAHOO,jQuery 的 jQuery($),DWR 的 dwr。比如我在 GE,写的控件可能就会以 ge. 开头。命名空间实际上就是借助对象的嵌套来实现,比如
题外话,选项
通常一个函数有可选参数的时候,大家会习惯性地将其放在函数签名的末尾。但如果可选参数比较多就不好看了。可以通过这样的方式来提供可选参数,
fun 函数带一个 param1 参数和一个 optionalParams 可选参数。这个 optionalParams 实际上代表了一个可选参数的集合。比如我可以这样调用,
DWR 使用类似这样的方式来实现功能丰富的回调,而 jQuery 无疑是这方面最强大的库。结合 jQuery 的变量继承,可选参数的实现变得非常简单。因为通过继承,可选参数的默认值可以很容易地指定。
参考
這樣改應該就可以了....
这样相当于给每个tBody添加了两个方法。
如果不喜欢这样做,也可以返回仅包含这两个方法的对象:
return {addRow:function(text){addRow.call($table,text)},removeRow:function(index){removeRow.call($table,index)}}
但这样就t1.addRow!==t2.addRow了。
为了演示或者您试验,请先准备好下面的 HTML 模板。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css"> body, body * { font: 10pt Arial; } .tbl { border-style: solid; border-width: 1px; width: 500px; table-layout: fixed; } .tbl thead { background-color: #555; color: #FFF; } .tbl tbody td { border-style: solid; border-width: 1px; } </style> <script type="text/javascript"> </script> </head> <body> <input type="button" value="Insert A Row" /><br /> <input type="text" id="indexText" /> <input type="button" value="Remove A Row" /><br /> <table class="tbl"> <thead> <tr> <td>Col A</td> <td>Col B</td> </tr> </thead> <tbody id="tblbody"> </tbody> </table> </body> </html>
这个页面包含一个两列的表格。"Insert A Row" 这个按钮意在向此表中添加一行。"Remove A Row"意在从此表中删除一行。在文本框中指定要删除的行号(从一开始索引)。
第一种,基于单个对象
var tableObj = (function() { var count = 0; var validateIndex = function(index) { if (index >= 1 && index <= count) return true; return false; }; return { addRow: function(a, b) { if (!a) a = ""; if (!b) b = ""; var tblBody = document.getElementById("tblbody"); var newRow = document.createElement("tr"); var colA = document.createElement("td"); colA.innerText = a; var colB = document.createElement("td"); colB.innerText = b; newRow.appendChild(colA); newRow.appendChild(colB); tblBody.appendChild(newRow); count += 1; }, removeRow: function(index) { if (!index) index = 0; if (!validateIndex(index)) { throw "Index out of range: " + index; return; } var tblBody = document.getElementById("tblbody"); var row = tblBody.childNodes[index]; tblBody.removeChild(row); count -= 1; } }; })();
这种方法被称为块模式(Module Pattern)。最后的“()”会导致那个匿名函数立即执行,从而返回 return 块的对象。这个返回的对象被赋给了 tableObj。其中,count 为 tableObj 的私有成员变量,validateIndex() 函数为其私有成员函数。
为了看看效果,将上面的代码放在 <script> 标签之中。然后为“Insert A Row”按钮添加 onclick="insertARow()",为“Remove A Row”按钮添加 onclick="removeARow()"。最后,在 <script> 标签中再加入下面的两个函数,
function insertARow() { tableObj.addRow("hi", "hello"); } function removeARow() { var index = document.getElementById("indexText").value; if (/^\d+$/.test(index)) { index = index / 1; } else { alert("Not a number"); return; } try { tableObj.removeRow(index); } catch (err) { alert(err); } }
这样,按钮的事件响应函数就添加完成了。现在您打开页面,应该就可以试验一下效果了。这种方法的优点是短平快,缺点是复用性较差。当然,这里指的不是 copy-paste 式的复用
假设有这样一个用例,还是这个页面,现在我需要再添加一个结构一样的表。难道要我们把上面的代码复制一遍吗?当然不。如果能支持以 new 的方法创建的话是最理想的。下面将介绍的方法基于类型,即构造函数。它是可以支持以 new 的方式创建对象的。
第二种,基于类型
var TableClass; (function() { /* Private static members */ var _debug = function(src, msg) { if (window.console) { window.console.log("[TableClass] " + src + ": " + msg); } }; // Constructor TableClass = function(tbodyId) { TableClass.instances.push(this); /* Private member fields */ var count = 0; /* Private member functions */ var validateIndex = function(index) { _debug("validateIndex()", "count: " + count); if (index >= 1 && index <= count) return true; return false; }; /* Initializer */ (function() { TableClass.instances.push(this); })(); /* Public member funcitons */ this.addRow = function(a, b) { _debug("addRow()", "count: " + count); if (!a) a = ""; if (!b) b = ""; var tblBody = document.getElementById(tbodyId); var newRow = document.createElement("tr"); var colA = document.createElement("td"); colA.innerText = a; var colB = document.createElement("td"); colB.innerText = b; newRow.appendChild(colA); newRow.appendChild(colB); tblBody.appendChild(newRow); count += 1; }; this.removeRow = function(index) { _debug("removeRow()", "count: " + count); if (!index) index = 0; if (!validateIndex(index)) { throw "Index out of range: " + index; return; } var tblBody = document.getElementById(tbodyId); var row = tblBody.childNodes[index]; tblBody.removeChild(row); count -= 1; } }; /* Public static members */ TableClass.instances = []; })();
这样的模式目前我还不知道是否有正式的名称。不过就目前我所知道的,网上各位作者仍然把类似这种基于类型的方法称为块模式。我认为,上面的模式就实现的功能来说是最优秀的。因为它能实现私有成员、私有静态、公有成员及公有静态。我将其称为类模式(Class Pattern)。
注意,公有成员函数 addRow() 和 removeRow() 在代码中使用了一个私有成员变量 tbodyId。而只有 TableClass 的构造函数带一个 tbodyId 的参数。就是这个 tbodyId 充当了私有成员变量。如果您觉得这样不好看,也可以在构造函数中加上这样一句话,
var _tbodyId = tbodyId;
然后把那两处引用 tbodyId 的地方改成 _tbodyId。看您的喜好了。
将第一个例子改造,添加一个结构相同的表。首先添加 HTML,
<table class="tbl"> <thead> <tr> <td>Col A</td> <td>Col B</td> </tr> </thead> <tbody id="tblbody2"> </tbody> </table>
然后初始化两个表对象,
var tableObj = new TableClass("tblbody"); var table2Obj = new TableClass("tblbody2");
最后改造按钮的事件响应函数,
function insertARow() { tableObj.addRow("hi", "hello"); table2Obj.addRow("hello", "hi"); // added this row. } function removeARow() { var index = document.getElementById("indexText").value; if (/^\d+$/.test(index)) { index = index / 1; } else { alert("Not a number"); return; } try { tableObj.removeRow(index); table2Obj.removeRow(index); // added this row. } catch (err) { alert(err); } }
OK。现在如果您点击“Insert A Row”应该可以看到两列内容相反但结构一致的表了。为了验证我们的公共静态成员 instances 是否有效,创建一个单独的按钮,
<input type="button" value="Count table instances" onclick="alert(TableClass.instances.length)" /><br />
点击“Count table instances”,结果会显示“2”。
题外话,命名空间
为了避免全局名字污染,通常我们写的控件都会放一个全局名称之下。像 YUI 的 YAHOO,jQuery 的 jQuery($),DWR 的 dwr。比如我在 GE,写的控件可能就会以 ge. 开头。命名空间实际上就是借助对象的嵌套来实现,比如
if (!dwr) var dwr = {}; if (!dwr.util) dwr.util = {}; dwr.util.escapeHtml = function(...) { ... };
题外话,选项
通常一个函数有可选参数的时候,大家会习惯性地将其放在函数签名的末尾。但如果可选参数比较多就不好看了。可以通过这样的方式来提供可选参数,
function fun(param1, optionalParams) { if (!optionalParams) optionalParams = {}; ... if (optionalPrams.timeout) { ... } }
fun 函数带一个 param1 参数和一个 optionalParams 可选参数。这个 optionalParams 实际上代表了一个可选参数的集合。比如我可以这样调用,
fun("param1", { timeout: 1000 });
DWR 使用类似这样的方式来实现功能丰富的回调,而 jQuery 无疑是这方面最强大的库。结合 jQuery 的变量继承,可选参数的实现变得非常简单。因为通过继承,可选参数的默认值可以很容易地指定。
参考
- A JavaScript Module Pattern
- YUI’s “Module Pattern” vs. Prototype’s Class Function
- Advantages of using the Module Pattern to Structure Javascript Classes
评论
12 楼
yangdong
2009-01-18
我塞,才看见,这帖子竟然被投了11票隐藏……看来我这篇文章写的不是一般烂啊
11 楼
yangdong
2009-01-18
是这样。那外句话就是为了演示静态成员用的。不过写其实控件时经常会用到。
10 楼
hanjs
2009-01-17
TableClass.instances.push(this);
/* Private member fields
*/
var count = 0;
上面的push是不是多余的?
/* Private member fields
*/
var count = 0;
上面的push是不是多余的?
9 楼
yangdong
2009-01-17
没错,我觉得这样应该就完美了。
8 楼
ylz4647
2009-01-16
<SCRIPT LANGUAGE="JavaScript"> <!-- var TableClass; (function() { /* Private static members */ var _debug = function(src, msg) { if (window.console) { window.console.log("[TableClass] " + src + ": " + msg); } }; // Constructor TableClass = function(tbodyId) { TableClass.instances.push(this); /* Private member fields */ var count = 0; /* Private member functions */ var validateIndex = function(index) { _debug("validateIndex()", "count: " + count); if (index >= 0 && index <= count) return true; return false; }; /* Initializer */ (function() { TableClass.instances.push(this); })(); /* Public member funcitons */ this._tbodyId = tbodyId; if(typeof TableClass.prototype.addRow == "undefined"){ TableClass.prototype.addRow = function(a, b) { _debug("addRow()", "count: " + count); if (!a) a = ""; if (!b) b = ""; var tblBody = document.getElementById(this._tbodyId); var newRow = document.createElement("tr"); var colA = document.createElement("td"); colA.innerText = a; var colB = document.createElement("td"); colB.innerText = b; newRow.appendChild(colA); newRow.appendChild(colB); tblBody.appendChild(newRow); count += 1; } }; if(typeof TableClass.prototype.removeRow == "undefined"){ TableClass.prototype.removeRow = function(index) { _debug("removeRow()", "count: " + count); if (!index) index = 0; if (!validateIndex(index)) { throw "Index out of range: " + index; return; } var tblBody = document.getElementById(this._tbodyId); var row = tblBody.childNodes[index]; tblBody.removeChild(row); count -= 1; } }; }; /* Public static members */ TableClass.instances = []; })(); //--> </SCRIPT>
這樣改應該就可以了....
7 楼
天下有鹏
2008-11-12
1。在js里面this始终是指向调用者。
2。如果对象化js,应该保持多实例调用的是同一个对象的方法。
3。私有变量尽量用_开始定义例如 : var _xxx;
2。如果对象化js,应该保持多实例调用的是同一个对象的方法。
3。私有变量尽量用_开始定义例如 : var _xxx;
6 楼
yangdong
2008-10-29
看来目前还没有十分完美的方法了。没想到给 DOM 添加自定义方法会有正式的用处。不过就目前所说,我倾向于我自己的方法。浪费点内存,但能保证信息隐藏。
5 楼
s79
2008-10-28
又要保证this的语义,又要t1.addRow===t2.addRow的话,就必须暴露私有变量,并使用原型的方式来定义对象了。比如:
这样的话,var table=new tableBody('xxx');得到的对象的table属性是私有属性,但为了传递给其公有方法,必须绑定在该对象上。私有属性也能被外部访问了,不能隐藏。
因为每次执行该函数的时候,tbody都不尽相同,这时要么把这个函数作为一个“工具函数”使用,如TableManager.addRow(HTMLElement tbody,Array text),要么使用this关联到tbody,如上面的prototype里边的两个函数,this.table就是这个tbody。
t1.addRow === t2.addRow 的好处应该是能节省内存,多次定义一个内容相同的函数,和只有一个函数,肯定后者比较好。
另外,给DOM添加自定方法,在mootools里被发挥的淋漓尽致,除了IE的其他浏览器如Firefox2,3/Opera9/Safari3/Chrome都有这两个对象,扩展Element和Event的prototype,就相当于给所有DOM对象和Event对象添加方法。但IE系列对HTMLElement和Event没有抽象的“类”对象,mootools就把扩展的方法逐一直接以赋值的方式赋给每个他用$获取的DOM对象。
IE8里提供了Element和Event这两个对象,也可以直接扩展了。这样对于OO方式的编程来说方便了很多。就不用“工具函数”的方法传参了。
function tableBody(id) { this.table=document.getElementById(id); } tableBody.prototype= { addRow:function(){...}, removeRow:function(){...} };
这样的话,var table=new tableBody('xxx');得到的对象的table属性是私有属性,但为了传递给其公有方法,必须绑定在该对象上。私有属性也能被外部访问了,不能隐藏。
因为每次执行该函数的时候,tbody都不尽相同,这时要么把这个函数作为一个“工具函数”使用,如TableManager.addRow(HTMLElement tbody,Array text),要么使用this关联到tbody,如上面的prototype里边的两个函数,this.table就是这个tbody。
t1.addRow === t2.addRow 的好处应该是能节省内存,多次定义一个内容相同的函数,和只有一个函数,肯定后者比较好。
另外,给DOM添加自定方法,在mootools里被发挥的淋漓尽致,除了IE的其他浏览器如Firefox2,3/Opera9/Safari3/Chrome都有这两个对象,扩展Element和Event的prototype,就相当于给所有DOM对象和Event对象添加方法。但IE系列对HTMLElement和Event没有抽象的“类”对象,mootools就把扩展的方法逐一直接以赋值的方式赋给每个他用$获取的DOM对象。
IE8里提供了Element和Event这两个对象,也可以直接扩展了。这样对于OO方式的编程来说方便了很多。就不用“工具函数”的方法传参了。
4 楼
yangdong
2008-10-27
您这样谢确实可以解决 t1.addRow === t2.addRow。好处是可以节省内存吗?我注意到,您的想法似乎是 hack 这个表的 DOM 对象。但我认为有充分的理由应该把自己的对象和 DOM 对象区分开,控件越复杂越是如此。
还有一个对于我来说最大的问题,就是实例方法里,我希望 this 指向我们自己编写的 table 脚本对象,而不是 DOM 对象。因为自己写的控件里会涉及自定义事件的触发,this 如果指向自身的话会十分方便。this 指向自身在我看来正是区分实例方法与静态方法的意义所在。也正是因为这个原因,我没有使用我参考里所列文章里的方法。使用他们的方法在调私有方法时必须用 addRow.call(this, ...)来保证 this 的语义。代码看起来非常乱,就我个人的经验来说,很容易出错,而且急难调试。如果忘记用 call 来调用,只会在被调函数内部出错,调用方不会有问题。
或者,您有方法既可以保证我所说的 this 的语义,同时还能使 t1.addRow === t2.addRow?
欢迎探讨!
还有一个对于我来说最大的问题,就是实例方法里,我希望 this 指向我们自己编写的 table 脚本对象,而不是 DOM 对象。因为自己写的控件里会涉及自定义事件的触发,this 如果指向自身的话会十分方便。this 指向自身在我看来正是区分实例方法与静态方法的意义所在。也正是因为这个原因,我没有使用我参考里所列文章里的方法。使用他们的方法在调私有方法时必须用 addRow.call(this, ...)来保证 this 的语义。代码看起来非常乱,就我个人的经验来说,很容易出错,而且急难调试。如果忘记用 call 来调用,只会在被调函数内部出错,调用方不会有问题。
或者,您有方法既可以保证我所说的 this 的语义,同时还能使 t1.addRow === t2.addRow?
欢迎探讨!
3 楼
s79
2008-10-27
<!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" xml:lang="zh-cn" lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>test</title> <script type="text/javascript"> ... </script> </head> <body> <table width="200" cellspacing="0" cellpadding="0" border="1"> <tbody id="tbody_1"/> </table> <table width="200" cellspacing="0" cellpadding="0" border="1"> <tbody id="tbody_2"/> </table> </body> </html>
var getTableBody=function() { function addRow(text) { var $tr=this.insertRow(-1); for(var i=text.length;i;i--) { var $td=$tr.insertCell(0); $td.innerHTML=text[i-1]; } } function removeRow(index) { this.deleteRow(index); } return function(id) { var $table=document.getElementById(id); $table.addRow=addRow; $table.removeRow=removeRow; return $table; }; }(); window.onload=function() { var t1=getTableBody("tbody_1"); var t2=getTableBody("tbody_2"); t1.addRow([1,2]); t2.addRow([3,4,5]); alert(t1.addRow===t2.addRow); }
这样相当于给每个tBody添加了两个方法。
如果不喜欢这样做,也可以返回仅包含这两个方法的对象:
return {addRow:function(text){addRow.call($table,text)},removeRow:function(index){removeRow.call($table,index)}}
但这样就t1.addRow!==t2.addRow了。
2 楼
yangdong
2008-10-23
不好意思,这阵子太忙,没有回。您能写一段代码演示一下吗?
1 楼
s79
2008-10-17
其实第二种方法的 addRow removeRow 方法,在每次调用的时候都是不同的function(作用域不同)。
不想使用不必要的this.xxx绑定私有变量,从而使用prototype来实现公有函数的话,把 addRow removeRow 放在闭包里、返回体外,就能让他们在每次调用的时候保持一致。
tableObj.addRow === tableObj2.addRow; //true
不想使用不必要的this.xxx绑定私有变量,从而使用prototype来实现公有函数的话,把 addRow removeRow 放在闭包里、返回体外,就能让他们在每次调用的时候保持一致。
tableObj.addRow === tableObj2.addRow; //true
发表评论
-
TimSort 中的核心过程
2011-09-11 20:19 4308TimSort 是 Python 中 list.sor ... -
模拟实现一个 Ruby 的 TCO
2011-05-15 00:24 1048今天搜了一下,发现 ruby 只有一部分 VM 实现支持 TC ... -
解决Ruby脚本在Windows命令行乱码
2011-05-08 16:08 1342如果把 ruby 当脚本使用,在 windows 命令行下面输 ... -
完全由不变体写出来的 Register Machine Simulator
2010-11-19 09:41 1349SICP 第二版 5.2 节提到的 Register Mach ... -
在 Clojure 中处理异常
2010-11-18 23:54 1517Update: As of Clojure 1.3, Cloj ... -
Named arguments in Clojure
2010-11-18 23:54 1093Clojure doesn't provide direct ... -
快速排序
2010-11-18 23:51 1188看了《The Joy of Clojure》的快速排序,觉得比 ... -
求对数
2010-11-18 23:46 1134下面是求以 1.12 为底,2.7 的对数。本方法极其低效,仅 ... -
Stream in Clojure
2010-11-18 23:40 1415(define fibs (stream-cons ... -
[Groovy] this 语义的陷阱
2009-07-30 21:46 967groovy 中 this 的语义有问题。下面的代码会报异常, ... -
firstChild 把我玩了
2008-07-31 23:23 1345加班两三个小时,就是因为被一个 DWR 的函数给玩了。dwr. ... -
方便的文件树遍历
2008-06-16 12:15 979我经常会遇到进行批量文件修改的情况。Windows 脚本我十分 ...
相关推荐
总而言之,学习现代JavaScript面向对象编程,有助于开发者在认识这门语言演化的基础上,运用面向对象的设计和编程模式来构建更加健壮和可维护的JavaScript应用程序。同时,测试和调试是保证代码质量不可或缺的环节,...
JavaScript,作为一种广泛应用...JavaScript 面向对象程序设计——继承与多态.pdf 和 JavaScript 面向对象程序设计——封装.pdf 这两个文档可能深入探讨了这些主题,帮助读者深入理解并掌握JavaScript的面向对象开发。
JavaScript是一种广泛应用于Web开发的动态编程语言,尤其在构建交互式网页和富互联网应用...《JavaScript面向对象编程指南》这本书将帮助你进一步探索这个主题,通过实例和详细的解释,提升你的JavaScript编程技能。
本文旨在深入解析JavaScript面向对象编程的基础,包括对象的基本概念、类与对象的关系、对象的属性与方法、封装、继承与多态,以及JavaScript中对象的实现方式。 #### 对象的基本概念 面向对象编程的核心在于对...
"javascript面向对象框架"这一主题涵盖了JavaScript中实现面向对象编程的框架,特别是Prototype和MooTools这两个优秀的库。 Prototype是JavaScript的一个开源库,它扩展了JavaScript的基本对象和函数,提供了强大的...
在JavaScript中,面向对象编程(OOP)是其核心概念之一,允许开发者通过类和对象来组织和管理代码,提高代码的可重用性和可维护性。 8.1 面向对象术语 面向对象编程的基础包括类、对象、继承和多态等概念。类是对象...
在深入讲解JavaScript面向对象与原型的知识点之前,首先需要了解JavaScript的基础知识。在JavaScript中,面向对象编程(OOP)的概念虽然存在,但是它的实现与传统基于类的语言有所不同。ECMAScript,也就是...
总结来说,JavaScript面向对象编程涵盖了从基本原理到实现细节的多个方面,包括但不限于对象、构造函数、原型链、继承以及封装等。本书系统地介绍了这些知识点,并通过实例演示了如何在现代JavaScript中实现OOP,...
### JavaScript面向对象编程详解 #### 一、JavaScript面向对象编程简介 JavaScript作为一种广泛使用的脚本语言,虽然起源于一种简单的浏览器脚本环境,但随着时间的发展,它已经演变为一种功能强大的编程语言,...
在JavaScript中,null和undefined是两个特殊的值。null表示一个变量不对应任何的值或对象,而undefined表示一个变量未定义或未赋值。 函数在JavaScript中是一种特殊的对象类型,可以作为值赋给变量、作为参数传递给...
JavaScript是一种广泛应用于Web开发的动态、弱类型、基于原型的脚本语言,它不仅支持函数式编程,还具有强大的面向对象编程能力...通过阅读《javascript面向对象编程.pdf》这样的资料,你可以深入理解并掌握这些概念。
原型是JavaScript面向对象编程的一个核心概念,每个对象都有一个原型对象,通过它可以继承其他对象的属性和方法。 程序示例分析: 在文档提供的代码示例中,Lecture类和Schedule类展示了如何在JavaScript中实现面向...
### JavaScript面向对象编程详解 #### 一、引言 随着Web技术的发展,特别是Ajax的兴起,JavaScript作为一种在浏览器端执行的脚本语言,其地位变得越来越重要。在现代Web应用中,JavaScript不再仅仅用于简单的页面...
下面我们将详细探讨JavaScript面向对象的基础知识。 1. **对象和数据类型**: 在JavaScript中,一切都是对象,包括基本数据类型(如字符串、数字、布尔值)。然而,与数字或字符串不同,对象是键值对的集合,可以...
在本篇文章中,作者详细阐述了JavaScript面向对象编程的几个关键特性,并通过代码示例展示了这些特性的具体应用。首先,我们来了解几个核心概念:类、静态成员、对象和重载。 类在面向对象编程中扮演着基础的角色,...
JavaScript 面向对象编程 JavaScript 面向对象编程是指使用 JavaScript 语言来实现面向对象编程的编程范式。面向对象编程是一种编程方法,它强调使用对象和类来描述和解决问题。在 JavaScript 中,我们可以使用类和...
以下是对JavaScript面向对象和原型机制的详细解释: 1. 面向对象的基本概念: - 类:在许多面向对象语言中,类是创建对象的模板,但在JavaScript中没有类的概念。 - 对象:JavaScript中的对象是一组键值对,可以...
存在两个重要的常量`Number.MAX_VALUE`和`Number.MIN_VALUE`,分别表示JavaScript能够表示的最大和最接近于零的数值。 - **全局Number对象的属性**:包括`NaN`(非数字)、`Infinity`(正无穷)、`Number.POSITIVE...