js两种定义函数、继承方式及区别

一:js两种定义函数的方式及区别

  • 1:函数声明:
function  sayA() {   alert("i am A");  }
  • 2:函数表达式:
var sayB = function() {   alert("i am B");  }
  • 区别:code
前者会在代码执行之前提前加载到作用域中,后者则是在代码执行到那一行的时候才会有定义

二:js两种继承方式及区别

  • 对象冒充

    • 临时属性
    • call()
    • apply()
  • 原型链 code
  • 继承应选哪种 code

三:实例

js两种定义函数的方式:

<!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函数体内(执行作用域)声明的变量,无论在函数体何处声明,它将都会被提升到函数的顶部,我们称这种现象为变量提升。
函数呢,它也有这种特性,即无论在函数体何处声明另一个函数,它将都会被提升到函数的顶部。
只是采用函数表达式和函数声明所体现的函数提升的内容是有差别的:函数表达式和变量提升类似,只会提升函数的变量,不提升函数的定义;
而函数声明提升时,不仅仅会提升函数的声明,函数的定义也会被提升

对象冒充:临时属性

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():

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

原型链继承:无new

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方式定义的变量和方法,如以下代码将会出错:

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()没有参数。

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();

结论:

成员变量采用对象冒充方式,成员方法采用原型链方式

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();

js两种定义函数、继承方式及区别

时间: 2024-12-31 18:04:02

js两种定义函数、继承方式及区别的相关文章

函数 两种定义函数的方式

函数声明 function foo () {} 函数表达式 var foo = function () {} (function() {})() var foo = function bar() {} return function () {} 函数声明会被提前 var sum = add(1,2); // 3 console.log(sum); function add(x, y) { x = +x; y = +y; if(isNaN(x) || isNaN(y)) { return; } r

Javascript学习笔记:3种定义函数的方式

①使用函数声明语法定义函数 1 function sum(num1,num2){ 2 return num1+num2; 3 } ②使用函数表达式定义函数 1 var sum=function(num1,num2){ 2 return num1+num2; 3 } ③使用Function构造函数定义函数 1 var sum=new Function('num1','num2','return num1+num2'); 三种定义函数的方式,其中第二和第三种从技术角度讲都属于函数表达式的方式,但是不

javascript两种声明函数的方式的一次深入解析

声明函数的方式 javascript有两种声明函数的方式,一个是函数表达式定义函数,也就是我们说的匿名函数方式,一个是函数语句定义函数,下面看代码: /*方式一*/ var FUNCTION_NAME = function() { /* FUNCTION_BODY */}; /*方式二*/ function FUNCTION_NAME () { /* FUNCTION_BODY */}; 区别一 方式一的声明方式是先声明后使用 方式二的声明方式可以先调用,后声明 /*方式一: *先声明后使用 *

javascript中两种定义函数方式的差别以及函数的预编译效果

我们知道在javascript中定义函数的方式有以下两种: function mm(){ } 这种形式是声明一个函数,跟 var 声明一个变量机制一样,脚本在解释执行之前会做预编译处理. var mm = function(){ } 这种形式是对一个变量赋值,虽然也做预编译,但仅仅只是给 mm 事先变量分配一个内存空间,而没有做初始化. 代码1: alert(a);//打印函数a的内存 alert(b);//undefined alert(c);//JS报错:"c"未定义 functi

JS两种声明函数的方法以及调用顺序

两种声明方法: 1. var a = function () {...}; 2. function a() {...}; 第一种方式必须先声明后调用,而第二种方式函数调用在声明之前之后都可以. //第一种方式 //a();这样调用会出错 var a = function () { alert("A"); } a();//A //第二种方式 b();//B function b() { alert("B"); } b();//B

ext.js 两种局部刷新的方式

$.ajax({ type: "POST", url: "AjaxAlgorithmOptimzeHandler.ashx?cmd=yhtrafficFlow", data: 'encoded=' + encoded, dataType: 'json', success: function (msg) {//msg其实就是Car类的一个实例 等价 car1 alert(msg); } }); 1 listeners: { 2 click: function (a,

C语言两种定义字符串的方式

/** * 1.字符串的定义方式 */ //可变字符串(放到栈里边)栈里边放局部变量有几份变量就有几个内存空间 char name[4] = "zkz"; char name3[4] = "zkz"; printf("name[4] = %p\n",name);//name[4] = 0x7fff5fbff79c printf("name3[4] = %p\n",name3);//name3[4] = 0x7fff5fbff7

JavaScript中的函数的两种定义方式

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script type="text/javascript"> /*I总结: 1.函数名可以做变量使用,可以赋值,可以传值 2.函数名当参数,传递给另一个函数 */ //==================js中函

Delphi函数指针的两种定义(对象方法存在一个隐藏参数self,所以不能相互赋值)

delphi中经常见到以下两种定义 Type TMouseProc = procedure (X,Y:integer); TMouseEvent = procedure (X,Y:integer) of Object; 两者样子差不多但实际意义却不一样, TMouseProc只是单一的函数指针类型; TMouseEvent是对象的函数指针,也就是对象/类的函数/方法 区别在于类方法存在一个隐藏参数self,也就是说两者形参不一样,所以不能相互转换 这也就是为什么delphi中可以这样赋值 but