精通javascript:面向对象的js
2012-09-06 11:33 youxin 阅读(321) 评论(0) 编辑 收藏 举报javascript 引用
/ Set obj to an empty object var obj = new Object(); // objRef now refers to the other object var objRef = obj; // Modify a property in the original object obj.oneProperty = true; // We now see that that change is represented in both variables // (Since they both refer to the same object) alert( obj.oneProperty == objRef.oneProperty );
var items = new Array( "one", "two", "three" );
// Create a reference to the array of items
var itemsRef = items;
// Add an item to the original array
items.push( "four" );
// The length of each array should be the same,
// since they both point to the same array object
alert( items.length == itemsRef.length );
// Set items to an array (object) of strings var items = new Array( "one", "two", "three" ); // Set itemsRef to a reference to items var itemsRef = items; // Set items to equal a new object items = new Array( "new", "array" ); // items and itemsRef now point to different objects. // items points to new Array( "new", "array" ) // itemsRef points to new Array( "one", "two", "three" ) alert( items != itemsRef );
// Set item equal to a new string object var item = "test"; // itemRef now refers to the same string object var itemRef = item; // Concatenate some new text onto the string object // NOTE: This creates a new object, and does not modify // the original object. item += "ing"; 创建了一个新的对象,不是修改 // The values of item and itemRef are NOT equal, as a whole // new string object has been created alert( item != itemRef );
foo="test";
}
test();
document.write(window.foo=="test");
// Create a new anonymous function, to use as a wrapper (function(){ // The variable that would, normally, be global var msg = "Thanks for visiting!"; // Binding a new function to a global object window.onunload = function(){ // Which uses the 'hidden' variable alert( msg ); }; // Close off the anonymous function and execute it }());
var obj=document.getElementById("main"); var items=["click","keypress"]; for(var i=0;i<items.length;i++) { var item=items[i]; obj['on'+item]=function(){ alert("thanks for your"+item); }; }
// An element with an ID of main var obj = document.getElementById("main"); // An array of items to bind to var items = [ "click", "keypress" ]; // Iterate through each of the items for ( var i = 0; i < items.length; i++ ) { // Use a self-executed anonymous function to induce scope (function(){ // Bind a function to the elment obj[ "on" + items[i] ] = function() { // items[i] refers to a parent variable that has been successfully // scoped within the context of this for loop alert( "Thanks for your " + items[i] ); }; })(); }
yes: function(){
// this == obj
this.val = true;
},
no: function(){
this.val = false;
}
};
// We see that there is no val property in the 'obj' object
alert( obj.val == null );
// We run the yes function and it changes the val property
// associated with the 'obj' object
obj.yes();
alert( obj.val == true );
// However, we now point window.no to the obj.no method and run it 把window.no指向obj.no并执行之
window.no = obj.no;
window.no();
// This results in the obj object staying the same (as the context was
// switched to the window object)
alert( obj.val == true );
// and window val property getting updated.
alert( window.val == false );
function changeColor( color ) {
this.style.color = color;
}
// Calling it on the window object, which fails, since it doesn't
// have a style object
changeColor( "white" ); 在window对象中调用此函数会失败,因为widnow没有style属性。
// Find the element with an ID of main
var main = document.getElementById("main");
// Set its color to black, using the call method
// The call method sets the context with the first argument
// and passes all the other arguments as arguments to the function
changeColor.call( main, "black" ); 、、main颜色会是black
// A function that sets the color on the body element
function setBodyColor() {
// The apply method sets the context to the body element
// with the first argument, the second argument is an array
// of arguments that gets passed to the function
changeColor.apply( document.body, arguments );
}
// Set the background color of the body to black
setBodyColor( "black" );
// Creates a new Object object and stores it in 'obj'
var obj = new Object();
// Set some properties of the object to different values
obj.val = 5;
obj.click = function(){
alert( "hello" );
};
// Here is some equivalent code, using the {…} shorthand
// along with key-value pairs for defining properties
var obj = {
// Set the property names and values use key/value pairs
val: 5,
click: function(){
alert( "hello" );
}
};
对象的创建
js没有类的概念,
In JavaScript, objects can create
new objects, and objects can inherit from other objects. This whole concept is called
prototypal inheritance and will be discussed more later in the “Public Methods” section
。js对象本身可以创建新对象,而对象也可以继承自其它对象。这个概念叫“原型化继承)。
Fundamentally, though, there still needs to be a way to create a new object, no matter
what type of object scheme JavaScript uses. JavaScript makes it so that any function can also
be instantiated as an object. In reality, it sounds a lot more confusing than it is. It’s a lot like
having a piece of dough (which is a raw object) that is molded using a cookie cutter (which
is an object constructor, using an object’s prototype
// A simple function which takes a name and saves
// it to the current context
function User( name ) {
this.name = name;
}
// Create a new instance of that function, with the specified name
var me = new User( "My Name" );
// We can see that it's name has been set as a property of itself
alert( me.name == "My Name" );
// And that it is an instance of the User object
alert( me.constructor == User );
// Now, since User() is just a function, what happens
// when we treat it as such? 如果我们把它作为函数
User( "Test" );
// Since it's 'this' context wasn't set, it defaults to the global 'window'
// object, meaning that window.name is equal to the name provided
alert( window.name == "Test" );
因为this上下文对象没有指定,所以默认为全局的window对象。
上面展示了constructor属性的使用,这一属性在每个对象中都存在,并一直指向创建它的函数。这样一来就可以有效地复制对象了,
用同一个基类创建对象并赋予不同的属性。
// Create a new, simple, User object
function User() {}
// Create a new User object
var me = new User();
// Also creates a new User object (from the
// constructor reference of the first)
var you = new me.constructor();
// We can see that the constructors are, in fact, the same
alert( me.constructor == you.constructor );
现在我们知道如何创建简单的对象了,是时候添加一些让对象更有用的东西了---上下文相关方法contextual method和属性。
1.公共方法
Public methods are completely accessible by the end user within the context of the object. To
achieve these public methods, which are available on every instance of a particular object, you
need to learn about a property called prototype, which simply contains an object that will act
as a base reference for all new copies of its parent object. Essentially, any property of the prototype
will be available on every instance of that object. This creation/reference process gives
prototype包含了一个对象,该对象可以作为所有新副本的基引用(base reference)。本质来说,所有对象的元凶的属性都能在
该对象的每个实例中找到。
us a cheap version of inheritance, which I discuss in Chapter 3.
Since an object prototype is just an object, you can attach new properties to them, just
like any other object. Attaching new properties to a prototype will make them a part of every
object instantiated from the original prototype, effectively making all the properties public
(and accessible by all). Listing 2-22 shows an example of this
因为对象的原型也是对象,和其他任何对象一样,也可以添加新属性,给原型添加新属性的结果是由该原型实例化的每个对象都会获得这些属性,也就使这些属性公有化了(能被所有对象访问)。
// Create a new User constructor
function User( name, age ){
this.name = name;
this.age = age;
}
// Add a new function to the object prototype
User.prototype.getName = function(){
return this.name;
};
// And add another function to the prototype
// Notice that the context is going to be within
// the instantiated object
User.prototype.getAge = function(){
return this.age;
};
// Instantiate a new User object
var user = new User( "Bob", 44 );
// We can see that the two methods we attached are with the
// object, with proper contexts
alert( user.getName() == "Bob" );
alert( user.getAge() == 44 );
Simple constructors and simple manipulation of the prototype object is as far as most
JavaScript developers get when building new applications. In the rest of this section I’m going
to explain a couple other techniques that you can use to get the most out of your objectoriented
code.
2私有方法 private method
私有方法和私有变量只允许其他的私有方法,私有变量和特权方法访问,这种方法可以定义一些只让对象内部访问,而外部访问不到的代码,这一技巧来自于crockford的履历。
// A Object constructor that represents a classroom
function Classroom( students, teacher ) {
// A private method used for display all the students in the class
function disp() {
alert( this.names.join(", ") );
}
// Store the class data as public object properties
this.students = students;
this.teacher = teacher;
// Call the private method to display the error
disp();
}
// Create a new classroom object
var class = new Classroom( [ "John", "Bob" ], "Mr. Smith" );
// Fails, as disp is not a public property of the object
class.disp(); 调用会失败。
虽然很简单,但私有方法和私有变量在保证代码没有冲突的同时,允许你对用户能使用和能看到的内容有更好的控制。下一步,我们将了解特权方法,它是私有方法和公共方法的混合体。
3.特权方法Privileged Methods
Privileged methods is a term coined by Douglas Crockford to refer to methods that are able
to view and manipulate private variables (within an object) while still being accessible to
users as a public method. Listing 2-24 shows an example of using privileged methods.
特权方法用来指代那些在查看并处理(对象中)私有变量的同时允许用户以公共方法的方式访问的方法。
就是java的getter方法。
// Create a new User object constructor
function User( name, age ) {
// Attempt to figure out the year that the users was born
var year = (new Date()).getFullYear() – age;
// Create a new Privileged method that has access to
// the year variable, but is still publically available
this.getYearBorn = function(){
return year;
};
}
// Create a new instance of the user object
var user = new User( "Bob", 44 );
// Verify that the year returned is correct
alert( user.getYearBorn() == 1962 );
// And notice that we're not able to access the private year
// property of the object
alert( user.year == null );
本质上,特权方法是动态生成的,因为他们是运行时才添加到对象中的,而不是在代码第一次编译时就已经生成的,虽然这个技巧比
往对象的prototype上绑定一个简单的方法开销更大,但功能更强大,更灵活,下面展示了动态生成方法能实现的例子:
In essence, privileged methods are dynamically generated methods, because they’re added
to the object at runtime, rather than when the code is first compiled. While this technique is
computationally more expensive than binding a simple method to the object prototype, it is
also much more powerful and flexible. Listing 2-25 is an example of what can be accomplished
using dynamically generated methods.
// Create a new user object that accepts an object of properties
function User( properties ) {
// Iterate through the properties of the object, and make sure
// that it's properly scoped (as discussed previously)
for ( var i in properties ) { (function(){
// Create a new getter for the property
this[ "get" + i ] = function() {
return properties[i];
};
// Create a new setter for the property
this[ "set" + i ] = function(val) {
properties[i] = val;
};
})(); }
}
// Create a new user object instance and pass in an object of
// properties to seed it with
var user = new User({
name: "Bob",
age: 44
});
// Just note that the name property does not exist, as it's private
// within the properties object
alert( user.name == null );
// However, we're able to access its value using the new getname()
// method, that was dynamically generated
alert( user.getname() == "Bob" );
// Finally, we can see that it''s possible to set and get the age using
// the newly generated functions
user.setage( 22 );
alert( user.getage() == 22 );
这上面的代码没有正确设置上下文与闭包调用对象(caller object)的变量,所以不会正确执行。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通