最进在学习js类,说一个教程吧,打算从类的创建,到类的继承 到类的封装,一一讲下,顺便理理自己的思路: 这里先了解什么是js类:摘录别人文章要仔细看这是基础: 作者:F. Permadi
functionName([parameters]){functionBody};
Example D1: CODE: function add(a, b) { return a+b; } alert(add(1,2)); // 结果 3
var add=function(a, b)
{ return a+b; } alert(add(1,2)); // 结果 3 这个代码和前一个例子做了同样的事情。也许语法看起来比较奇怪,但它应该更能让你感觉到函数是一个对象,而且我们只是为这个对指派了一个名称。可以把它看做和 var myVar=[1,2,3]一样的语句。以这种方式声明的函数内容也一样会被编译。
var add=function theAdd(a, b)
{ return a+b; } alert(add(1,2)); // 结果 3 alert(theAdd(1,2)); // 结果也是 3
var myObject=new Object();
myObject.add=function(a,b){return a+b}; // myObject 现在有一个叫做“add”的属性(或方法) // 而且我能够象下面这样使用它 myObject.add(1, 2);
varName=new Function([param1Name, param2Name,...paramNName], functionBody);
Example D3:
var add=new Function("a", "b", "return a+b;");
alert(add(3,4)); // 结果 7 我在这里有两个参数叫做a和b,而函数体返回a和b的和。请注意new Function(...)使用了大写F,而不是小写f。 这就告诉javascript,我们将要创建一个类型是Function的对象。 还要注意到,参数名和函数体都是作为字符串而被传递。我们可以随心所欲的增加参数,javascript知道函数体会是右括号前的最后一个字符串(如果没有参数,你能够只写函数体)。你没必要将所有东西都写在一行里(使用/或者使用字符串连接符+来分隔长代码)。/标记告诉JavaScript在下一行查找字符串的其余部分。例子如下:
var add=new Function("a", "b",
"alert" + // 注意 "+" "('adding '+a+' and ' +b);/ // 和 "/"的不同用法 return a+b;"); alert(add(3,4)); // 结果 7 采用这种方式定义函数会导致函数并没被编译,而且它有可能会比用其它方式定义的函数要慢。至于为什么,看一下这个代码: function createMyFunction(myOperator) { return new Function("a", "b", "return a" + myOperator + "b;"); } var add=createMyFunction("+"); // 创建函数 "add" var subtract=createMyFunction("-"); // 创建函数 "subtract" var multiply=createMyFunction("*"); // 创建函数 "multiply" // test the functions alert("加的结果="+add(10,2)); // 结果是 12 alert("减的结果="+subtract(10,2)); // 结果是 8 alert("乘的结果="+multiply(10,2)); // 结果是 20 alert(add);
function Ball() // 也许看起来有点奇怪,但是这个声明
{ // 创建了一个叫做Ball的对象 i=1; } alert(typeof Ball); // 结果 "function"
function Ball() // 也许看起来有点奇怪,但是这个声明
{ // 创建了一个叫做Ball的对象,而且你能够 } // 引用它或者象下面那样给它增加属性 Ball.callsign="The Ball"; // 给Ball增加属性 alert(Ball.callsign); // 输出 "The Ball"
function myFunction(message)
{ alert(message); } var ptr=myFunction; // ptr指向了myFunction ptr("hello"); // 这句会执行myFunction:输出"hello"
function sayName(name)
{ alert(name); } var object1=new Object(); // 创建三个对象 var object2=new Object(); var object3=new Object(); object1.sayMyName=sayName; // 将这个函数指派给所有对象 object2.sayMyName=sayName; object3.sayMyName=sayName; object1.sayMyName("object1"); // 输出 "object1" object2.sayMyName("object2"); // 输出 "object2" object3.sayMyName("object3"); // 输出 "object3"
function myFunction() { alert(myFunction.message); } myFunction.message="old"; var ptr1=myFunction; // ptr1 指向 myFunction var ptr2=myFunction; // ptr2 也指向 myFunction ptr1(); // 输出 "old" ptr2(); // 输出 "old" myFunction.message="new"; ptr1(); // 输出 "new" ptr2(); // 输出 "new"
function myFunction()
{ alert("Old"); } myFunction(); // 输出 "Old" myFunction=function() { alert("New"); }; myFunction(); // 输出 "New"
function myFunction()
{ alert("Old"); } var savedFuncion=myFunction; myFunction=function() { alert("New"); }; myFunction(); // 输出 "New" savedFuncion(); // 输出 "Old"
function myFunction()
{ alert("Old"); } var savedFunc=myFunction; savedFunc=function() { alert("New"); }; myFunction(); // 输出 "Old" savedFunc(); // 输出 "New"
function getHalfOf(num1, num2, num3) { function calculate(number) { return number/2; } var result=""; result+=calculate(num1)+" "; result+=calculate(num2)+" "; result+=calculate(num3); } var resultString=getHalfOf(10,20,30); alert(resultString); // 输出 "5 10 15"
function calculate(number) { return number/3; } function getHalfOf(num1, num2, num3) { function calculate(number) { return number/2; } var result=""; result+=calculate(num1)+" "; result+=calculate(num2)+" "; result+=calculate(num3); } var resultString=getHalfOf(10,20,30); alert(resultString); // 输出 "5 10 15"
function Ball() { } var ball0=new Ball(); // ball0 现在指向一个新对象 alert(ball0); // 输出 "Object",因为 ball0 现在是一个对象
function Ball(message)
{ alert(message); } var ball0=new Ball("creating new Ball"); // 创建对象并输出消息 ball0.name="ball-0"; // ball0现在有一个属性:name alert(ball0.name); // 输出 "ball-0"
function Ball(message)
{ alert(message); } var ball0=new Object(); ball0.construct=Ball; ball0.construct("creating new ball"); // 执行 ball0.Ball("creating.."); ball0.name="ball-0"; alert(ball0.name);
function Ball() { } var ball0=new Ball(); // ball0 现在指向了类型Ball的一个新实例 ball0.name="ball-0"; // ball0 现在有一个属性"name" var ball1=new Ball(); ball1.name="ball-1"; var ball2=new Ball(); alert(ball0.name); // 输出 "ball-0" alert(ball1.name); // 输出 "ball-1" alert(ball2.name); // 哦,我忘记给ball2添加“name”了!
function Ball(message, specifiedName)
{ alert(message); this.name=specifiedName; } var ball0=new Ball("creating new Ball", "Soccer Ball"); alert(ball0.name); // prints "Soccer Ball"
function Ball(color, specifiedName, owner, weight) { this.name=specifiedName; this.color=color; this.owner=owner; this.weight=weigth; } var ball0=new Ball("black/white", "Soccer Ball", "John", 20); var ball1=new Ball("gray", "Bowling Ball", "John", 30); var ball2=new Ball("yellow", "Golf Ball", "John", 55); var balloon=new Ball("red", "Balloon", "Pete", 10); alert(ball0.name); // 输出 "Soccer Ball" alert(balloon.name); // 输出 "Balloon" alert(ball2.weight); // 输出 "55"
function Employee(name, salary, mySupervisor)
{ this.name=name; this.salary=salary; this.supervisor=mySupervisor; } var boss=new Employee("John", 200); var manager=new Employee("Joan", 50, boss); var teamLeader=new Employee("Rose", 50, boss); alert(manager.supervisor.name+" is the supervisor of "+manager.name); alert(manager.name+"/'s supervisor is "+manager.supervisor.name);
function Employee(name, salary) { this.name=name; this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=function() { return this.salary; }; } function addSalaryFunction(addition) { this.salary=this.salary+addition; } var boss=new Employee("John", 200000); boss.addSalary(10000); // boss 长了 10K 工资……为什么老板工资可以长这么多:'( alert(boss.getSalary()); // 输出 210K……为什么默认工资也那么高……:'(
function Employee(name, salary) { this.name=name; this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=function() { return this.salary; }; } function addSalaryFunction(addition) { this.salary=this.salary+addition; } var boss=new Employee("John", 200000); var boss2=new Employee("Joan", 200000); var boss3=new Employee("Kim", 200000);
function Employee(name, salary) { this.name=name; this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=function() { return this.salary; }; } function addSalaryFunction(addition) { this.salary=this.salary+addition; } var boss1=new Employee("John", 200000); var boss2=new Employee("Joan", 200000); // 给getSalary函数对象添加属性 boss1.getSalary.owner="boss1"; boss2.getSalary.owner="boss2"; alert(boss1.getSalary.owner); // 输出 "boss1" alert(boss2.getSalary.owner); // 输出 "boss2" // 如果两个对象指向同一个函数对象,那么 // 上面两个输出都应该是“boss2”。 // 给addSalary函数对象添加属性 boss1.addSalary.owner="boss1"; boss1.addSalary.owner="boss2"; alert(boss1.addSalary.owner); // 输出 "boss2" alert(boss2.addSalary.owner); // 输出 "boss2" // 因为两个对象都指向同一个函数,(子乌注:原文写are not pointing to the same function,疑为笔误) // 当修改其中一个的时候,会影响所有的实例(所以两个都输出“boss2”).
function Employee(name, salary) { this.name=name; this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=getSalaryFunction; } function getSalaryFunction() { return this.salary; } function addSalaryFunction(addition) { this.salary=this.salary+addition; }
function Test()
{ } alert(Test.prototype); // 输出 "Object"
function Fish(name, color)
{ this.name=name; this.color=color; } Fish.prototype.livesIn="water"; Fish.prototype.price=20;
var fish1=new Fish("mackarel", "gray");
var fish2=new Fish("goldfish", "orange"); var fish3=new Fish("salmon", "white");
for (int i=1; i<=3; i++)
{ var fish=eval("fish"+i); // 我只是取得指向这条鱼的指针 alert(fish.name+","+fish.color+","+fish.livesIn+","+fish.price); }
"mackarel, gray, water, 20"
"goldfish, orange, water, 20" "salmon, white water, 20"
function Employee(name, salary) { this.name=name; this.salary=salary; } Employee.prototype.getSalary=function getSalaryFunction() { return this.salary; } Employee.prototype.addSalary=function addSalaryFunction(addition) { this.salary=this.salary+addition; }
var boss1=new Employee("Joan", 200000);
var boss2=new Employee("Kim", 100000); var boss3=new Employee("Sam", 150000);
alert(boss1.getSalary()); // 输出 200000
alert(boss2.getSalary()); // 输出 100000 alert(boss3.getSalary()); // 输出 150000
明白了什么是类,接下来看下这两个以后要用到的属性:[摘录] function foo(x) { function bar(foo) { var func = bar(foo); 试验结果表明:apply以后,temp对象就继承了foo类的公有变量了。也就是说,这一句 foo.apply(temp, arguments);实际上就是把foo()函数当成temp对象的构造函数来调用了。一旦构造完毕,temp对象就具有了成员this.x。 这样,我有了两种理解方案: ①按照传统的面向对象的语言来理解:一般来说,构造函数是不能被外界(不包括派生类)访问的。因此,这句话“调用apply时,是把foo函数变成temp对象的方法,然后调用”是正确的,而“可是temp.foo竟然没有定义”则是理所当然的事情了。 ②按照JavaScript语言自身的对象机制来理解:在JavaScript中,(构造 )函数就是国王、一等公民,它就是类就是它。对象则是(构造)函数的实例。因此,通过对象来访问构造函数,显然是行不通的。
其实,说构造未必准确(但我们可以利用构造函数来理解这个处理过程),我认为应该说成克隆,也就是说系统把foo类拥有的所有公有变量复制给了temp对象(这里是指Object,Function,Array和包装型对象“四类”对象)。 蓝色的文字表明,如果temp不是一个对象型(指以上提到的四类对象)变量的话,克隆过程就不会发生,如下所示: foo.apply(0, arguments); 那么foo.apply()实际上就和普通的方法调用没有什么区别了,只是有了它,我们可以利用传递arguments参数的便利。 所以,apply(和call)的应用场合就浮现出来了: ①我们需要把一个类的公有变量复制给另一个对象。 ②我们要快速而“智能”的传参,而不是手动去书写arguments[0],arguments[1]...
问一个函数与函数之间传参数的问题,我觉得我这种方法太麻烦,不知道大家还有没有更好的方法. 如果按传统的方式来,得这样写: function user( ) { function test(id,name) { } user("dfdfd","kkkkk"); 这样写的缺点很明显,万一参数一变,程序就挂了。
而利用apply,程序就变聪明多了: function user( ) { function test(id,name) { } user("dfdfd","kkkkk");
apply(...)和call(...)确实很实用,比如实现一个类创建模式 <script type="text/javascript"> var Class = { var vehicle = Class.create(); var moto=new vehicle("Moto"); //--> |