[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[学习笔记]pro javascript techniques学习笔记2

上一篇:[转]IE 无法打开Internet站点,已终止操作
下一篇:[转]10个基于 JavaScript 的 WYSIWYG 编辑器

添加日期:2009/4/9 16:58:40 快速返回   返回列表 阅读3890次
学习笔记1-->>
http://www.mytju.com/classcode/news_readNews.asp?newsID=226


Context

上下文,这是面向对象语言的共通的特性,但是javascript里是很极端的。

Context是通过this变量工作的,this变量始终指向一个对象(代码当前在哪运行的那个对象)。

即使是全局Context,this变量也是指向window对象的。


<script>
var obj = {
    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
//当前Context是obj变量,所以this指向它,改变的是它的属性。
obj.yes();
alert( obj.val == true );

// However, we now point window.no to the obj.no method and run it
//Context变为window对象,改变的是它的属性
window.no = obj.no;
window.no();

// This results in the obj object staying the same (as the context was
// switched to the window object)
//所以obj的val属性是true
alert( obj.val == true );

// and window val property getting updated.
//window的val属性是false
alert( window.val == false );
</script>


四个结果全是true。

这样变更Context太麻烦,javascript提供了两个方法,使这个过程更容易理解和实现。


<div id="main">sssssssssssssssss</div>
<script>
// A simple function that sets the color style of its context
function changeColor( color ) {
    this.style.backgroundColor = color;
}
// Calling it on the window object, which fails, since it doesn't
// have a style object
//当前是window对象,此句会失败,
changeColor( "white" );

// 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
//使用call方法,第一个参数设置Context
changeColor.call( 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
    //使用apply方法,第一个参数设置Context,第二个参数是参数数组
    changeColor.apply( document.body, arguments );
}
// Set the background color of the body to black
setBodyColor( "yellow" );
</script>


整个页面背景是黄色,div的背景是黑色。需要注释掉changeColor( "white" );

面向对象基础

Object
Object是javascript的基础,事实上,everything都是Object。
在大部分基本层面来说,Object以属性集合的形式存在,类似于其他语言中的hash结构。


<script>
// 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" );
    }
};
</script>



Object Creation
与其他面向对象语言不通,javascript中没有class类的概念。
在javascript中,Object可以创建Object,可以从其他Object继承,这整个概念称为“prototypal inheritance”(原型继承)


任何function也可以当作Object对待。


<script>
// 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 its 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 its 'this' context wasn't set, it defaults to the global 'window'
// object, meaning that window.name is equal to the name provided
//没有指定,则this指向了window对象。
alert( window.name == "Test" );
</script>


结果都是true。

constructor属性,每个Object都有,指向创建它的function。

OK,下面看看如何创建一个新的Object,但不用名字。


<script>
// 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 );
</script>


结果是true。

现在已经知道如何创建简单的对象了,下面看一下如何增加属性和方法。

Public Methods
这里要了解一下prototype属性,它包含一个对象,对于所有Object的副本来说,这个对象都指向Object。
prototype的任何属性都可以被Object的所有实例访问。
所以,只要给prototype追加属性,那么原始Object的所有实例都拥有了这个属性,这个属性就是Public的了。


<script>
// Create a new User constructor
function User( name, age ){
    this.name = name;
    this.age = age;
}
// Add a new function to the object prototype
//给prototype追加属性来给User追加方法。
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 );
</script>



Private Methods
私有方法和变量,只能被其他私有方法,私有变量和特权方法(privileged methods)访问的。
它们只能在Ojbect内部访问,外部不可以。
这个技术主要基于Douglas Crockford的工作,它的网站有详细的文档。
http://javascript.crockford.com/
http://javascript.crockford.com/private.html


<script>
// An Object constructor that represents a classroom
function Classroom( students, teacher ) {
    // A private method used for displaying 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
//下面这句是错误的,不能访问disp方法。
class.disp();
</script>




Privileged Methods
特权方法还是Douglas Crockford这位大哥搞的,用来查看和操纵私有变量的Public方法。


<script language="javascript">
// Create a new User object constructor
function User( name, age ) {
    // Attempt to figure out the year that the user 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 );
</script>
我运行怎么没反应??


特权方法是动态生成的,因为它是运行时动态追加到Object的。

下面看一下动态生成的方法能干什么……


<script language="javascript">
/ 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)
    //遍历所有,动态生成get方法和set方法。
    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
//name属性是私有的,不能直接访问。
alert( user.name == null );

// However, we're able to access its value using the new getname()
// method, that was dynamically generated
//但是,我们可以通过get方法访问。
alert( user.getname() == "Bob" );

// Finally, we can see that it's possible to set and get the age using
// the newly generated functions
//还可以通过set方法设置值
user.setage( 22 );
alert( user.getage() == 22 );
</script>



哇塞,根据动态的变量创建代码,简直不可相信,太有用了……

Static Methods
静态方法背后的实质和其他正常的function是完全一致的,没什么不一样。
主要的不同就是:这个function是作为Object的一个静态属性存在的。
作为一个属性,Object的实例是不能访问的,只有在Object同样的Context里才能访问。
这和其他语言的静态方法有点像……

实际上,这样写代码的唯一优点是保持Object的namespace clean.


// A static method attached to the User object
User.cloneUser = function( user ) {
    // Create, and return, a new user
    return new User(
        // that is a clone of the other user object
        user.getName(),
        user.getAge()
    );
};



静态方法是我们遇到的第一个,纯粹是组织关系用的方法。
 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved