function sayA() { alert("i am A"); }
var sayB = function() { alert("i am B"); }
前者会在代码执行以前提早加载到做用域中,后者则是在代码执行到那一行的时候才会有定义
js两种定义函数的方式:javascript
<!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> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>js两种定义函数的方式</title> <script language="javascript"> say(); var say =function(){ alert("567"); } function say(){ alert("123"); } </script> </head> <body> </body> </html> //在javascript函数体内(执行做用域)声明的变量,不管在函数体何处声明,它将都会被提高到函数的顶部,咱们称这种现象为变量提高。 函数呢,它也有这种特性,即不管在函数体何处声明另外一个函数,它将都会被提高到函数的顶部。 只是采用函数表达式和函数声明所体现的函数提高的内容是有差异的:函数表达式和变量提高相似,只会提高函数的变量,不提高函数的定义; 而函数声明提高时,不单单会提高函数的声明,函数的定义也会被提高
对象冒充:临时属性html
function Person(name){ this.name = name; this.say = function(){ alert('My name is '+this.name); } } function Student(name,id){ this.temp = Person; this.temp(name); delete this.temp; this.id = id; this.showId = function(){ alert('Good morning,Sir,My student number is '+this.id); } } var simon = new Student('Simon',9527); simon.say(); //my name id simon simon.showId(); //Good morning,Sir,My work number is 9527
对象冒充:apply()/call():java
function Person(name){ this.name = name; this.say = function(){ alert('My name is '+this.name); } } function Student(name,id){ Person.call(this,name); //apply():Person.apply(this,new Array(name)); this.id = id; this.showId = function(){ alert('Good morning,Sir,My student number is '+this.id); } } var simon = new Student('Simon',9527); simon.say(); simon.showId(); //apply(this,arguments):方法能劫持另一个对象的方法,继承另一个对象的属性. arguments:是一个数组,new Array(name,age)等 //call(id,name,age) //什么状况下用apply,什么状况下用call 在给对象参数的状况下,若是参数的形式是数组的时候, 好比apply示例里面传递了参数arguments,这个参数是数组类型, 而且在调用Person的时候参数的列表是对应一致的(也就是Person 和Student的参数列表前两位是一致的) 就能够采用 apply , 若是个人Person的参数列表是这样的(age,name),而Student 的参数列表是(name,age,grade),这样就能够用call来实现了, 也就是直接指定参数列表对应值的位置(Person.call(this,age,name,grade)); //apply和call中的参数顺序以父类为准。
原型链继承:new数组
var Shape = function(width, height) { this.width = width; this.height = height; }; Shape.prototype.area = function() { return this.width * this.height }; var shape = new Shape(20, 30); shape.area(); > 600
原型链继承:无newapp
function Shape(width, height) { if (!(this instanceof Shape)) { return new Shape(width, height); } this.width = width; this.height = height; return this; } Shape.prototype.area = function() { return this.width * this.height }; var shape = Shape(20, 30); console.log(shape.area());
选择最优继承方式:函数
1:在OO概念中,new实例化后,对象就在堆内存中造成了本身的空间, 值得注意的是,这个代码段。而成员方法就是存在这个代码段的, 而且方法是共用的。问题就在这里,经过对象冒充方式继承时, 全部的成员方法都是指向this的,也就是说new以后,每一个实例将 都会拥有这个成员方法,并非共用的,这就形成了大量的内存浪费。 而且经过对象冒充的方式,没法继承经过prototype方式定义的变量和方法,如如下代码将会出错:ui
function Person(name){ this.name = name; this.say = function(){ alert('My name is '+this.name); } } Person.prototype.age = 20; Person.prototype.sayAge = function(){alert('My age is '+this.age)}; function Student(name,id){ Person.apply(this,new Array(name)); this.id = id; this.showId = function(){ alert('Good morning,Sir,My student number is '+this.id); } } var simon = new Student('Simon',9527); simon.sayAge(); //提示TypeError: simon.sayAge is not a function
2:原型链方式继承,就是实例化子类时不能将参数传给父类,这个例子中function Person()没有参数。this
function Person(name){ this.name = name; } Person.prototype.say = function(){ alert('My name is '+this.name); } function Student(name,id){ this.id = id; this.showId = function(){ alert('Good morning,Sir,My student number is '+this.id); } } Student.prototype = new Person(); //此处没法进行传值,this.name或者name都不行, //直接写Student.prototype = new Person('wood')是能够的, //可是这样的话simon.say()就变成了My name is wood var simon = new Student("Simon",9527); simon.say(); //弹出 My name is undefined simon.showId();
结论:spa
成员变量采用对象冒充方式,成员方法采用原型链方式 function Person(name){ this.name = name; } Person.prototype.say = function(){ alert('My name is '+this.name); } function Student(name,id){ Person.call(this,name); this.id = id; } Student.prototype = new Person(); //此处注意一个细节,showId不能写在Student.prototype = new Person();前面 Student.prototype.showId = function(){ alert('Good morning,Sir,My student number is '+this.id); } var simon = new Student("Simon",9527); simon.say(); simon.showId();