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

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

二: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两种定义函数、继承方式及区别的更多相关文章

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

    ①使用函数声明语法定义函数 function sum(num1,num2){ return num1+num2; } ②使用函数表达式定义函数 var sum=function(num1,num2){ ...

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

    声明函数的方式 javascript有两种声明函数的方式,一个是函数表达式定义函数,也就是我们说的匿名函数方式,一个是函数语句定义函数,下面看代码: /*方式一*/ var FUNCTION_NAME ...

  3. javascript定义函数不同方式的区别

    学习javascript中遇到了这么一个问题,代码如下: var test = 'a'; function test() { alert('Hello World!'); } alert(test); ...

  4. TF之RNN:TF的RNN中的常用的两种定义scope的方式get_variable和Variable—Jason niu

    # tensorflow中的两种定义scope(命名变量)的方式tf.get_variable和tf.Variable.Tensorflow当中有两种途径生成变量 variable import te ...

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

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

  6. get和post两种表单提交方式的区别

    今天看到一篇博客谈论get和post区别,简单总结一下https://www.cnblogs.com/logsharing/p/8448446.html 要说两者的区别,接触过web开发的人基本上都能 ...

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

    delphi中经常见到以下两种定义 Type TMouseProc = procedure (X,Y:integer); TMouseEvent = procedure (X,Y:integer) o ...

  8. OC中两种单例实现方式

    OC中两种单例实现方式 写在前面 前两天探索了一下C++ 的单例,领悟深刻了许多.今天来看看OC中的单例又是怎么回事.查看相关资料,发现在OC中一般有两种实现单例的方式,一种方式是跟C++ 中类似的常 ...

  9. Java中有两种实现多线程的方式以及两种方式之间的区别

    看到一个面试题.问两种实现多线程的方法.没事去网上找了找答案. 网上流传很广的是一个网上售票系统讲解.转发过来.已经不知道原文到底是出自哪里了. Java中有两种实现多线程的方式.一是直接继承Thre ...

随机推荐

  1. servlet+jsp+java实现Web 应用

    servlet+jsp+java实现Web 应用 用java来构建一个web应用是特别容易的事情,jsp和php很像,可以嵌套在html中.程序的结构很简单,也很清楚,本文主要记录下大概的开发过程和环 ...

  2. 小米Web前端JavaScript面试题

    面试题目 一. 请定义这样一个函数 function repeat (func, times, wait) { } 这个函数能返回一个新函数,比如这样用 var repeatedFun = repea ...

  3. MySQL数据库主键设计原则

    目录 1. 主键定义... 5 2. 主键设计原则... 5 2.1 确保主键的无意义性... 5 2.2 采用整型主键... 5 2.3 减少主键的变动... 5 2.4 避免重复使用主键... 6 ...

  4. 【转】The difference between categorical(Nominal ), ordinal and interval variables

    What is the difference between categorical, ordinal and interval variables? In talking about variabl ...

  5. Why we need model on Django ?

    step01: create a database name as (django_db) on mysql ... step02: configure your django to use the ...

  6. 每天一个linux命令(7):mv命令

    mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 企业中常用的 [root@ local]# ...

  7. Android组件Spinner使用

    Spinner组件是Android当中非常常用的一种用于下拉选择的组件. 本blog当中主要解决的几个问题: 如何在XML中初始化Spinner选项 如何使用代码的方式初始化Spinner选项 一个A ...

  8. [推荐]DDOS攻击与防范知识介绍

    [推荐]DDOS攻击与防范知识介绍 DDOS攻防体系建设v0.2(淘宝-林晓曦)     http://wenku.baidu.com/view/39549a11a8114431b90dd866.ht ...

  9. iOS-OC-APP热更新,动态更新(仿QQ打开或关闭某个功能)

    一.前言 iOS开发更新APP我觉得是比较坑的就是审核时间比较长,审核比较严,对于刚入行的小伙伴来说,雷区比较多:所以热更新是比较重要的: 大家也许会发现我们常用的QQ现在下来也就一百多兆,但是用了几 ...

  10. SQL Developer 4.0 启动报错“unable to create an instance of the java virtual machine located at path”

    安装了Oracle之后,第一件事情就是想想怎么去连接,进而操作.SQL Developer是官方提供的强大工具,个人看来也是第一选择. 目前官网提供的最新版是4.0.1.14.48,下载下来之后,就跃 ...