javascript中new关键字详解

和其他高级语言一样javascript中也有new关键字,我们以前认知的new是用来创建一个类的实例对象,但在js中万物皆是对象,为何还要new关键字呢,其实js中new关键字不是用来创建一个类的实例对象,而是用于继承。 接下来,本文将带你一起来探索JS中new的奥秘...

function Animal(name){
  this.name = name;
}
Animal.color = "black";
Animal.prototype.say = function(){
  console.log("I'm " + this.name);
};
var cat = new Animal("cat");

console.log(
  cat.name, //cat
  cat.height //undefined
);
cat.say(); //I'm cat

console.log(
  Animal.name, //Animal
  Animal.color //back
);
Animal.say(); //Animal.say is not a function

如果你能理解上面输出的结果,说明你已非常了解js中new和this的运行机制,请忽略本文!

我们将通过解析这个例子来加深你对js中new和继承的理解! 【如果你对js的this还不了解,请先阅读:JS作用域和this关键字】

一、代码解读

1-3行创建了一个函数Animal,并在其this上定义了属性:name,name的值是函数被执行时的形参。

第4行在Animal对象(Animal本身是一个函数对象)上定义了一个静态属性:color,并赋值“black”

5-7行在Animal函数的原型对象prototype上定义了一个say()方法,say方法输出了this的name值。

第8行通过new关键字创建了一个新对象cat

10-14行cat对象尝试访问name和color属性,并调用say方法。

16-20行Animal对象尝试访问name和color属性,并调用say方法。

二、重点解析

第8行代码是关键:

var cat = new Animal("cat");

JS引擎在执行这句代码时,做了很多工作,用伪代码模拟其工作流程如下:

 var obj = {};
 obj.__proto__ = Animal.prototype;
 var result = Animal.call(obj,"cat");
 return typeof result === 'obj'? result : obj;

(1)创建一个空对象obj;

(2)把obj的__proto__ 指向Animal的原型对象prototype,此时便建立了obj对象的原型链:obj->Animal.prototype->Object.prototype->null

【如果你不了解JS原型链,请先阅读:JS原型和原型链】

(3)在obj对象的执行空间调用Animal函数并传递参数“cat”。 相当于var result = obj.Animal("cat")。

当这句执行完之后,obj便产生了属性name并赋值为"cat"。【关于JS中call的用法请阅读:JS的call和apply】

(4)考察第3步返回的返回值,如果无返回值或者返回一个非对象值,则将obj返回作为新对象;否则会将返回值作为新对象返回。

了解了new的运行机制后,我们知道cat其实就是过程(4)的返回值,因此我们对cat对象的认知就多了一些:

cat的原型链是:obj->Animal.prototype->Object.prototype->null

cat上新增了一个属性:name

分析完了cat的产生过程,我们再看看输出结果:

cat.name -> 在过程(3)中,obj对象就产生了name属性。因此cat.name就是这里的obj.name

cat.color -> cat会先查找自身的color,没有找到便会沿着原型链查找,在上述例子中,我们仅在Animal对象上定义了color,并没有在其原型链上定义,因此找不到。

cat.say -> cat会先查找自身的say方法,没有找到便会沿着原型链查找,在上述例子中,我们在Animal的prototype上定义了say,因此在原型链上找到了say方法。

另外,在say方法中还访问this.name,这里的this指的是其调用者obj,因此输出的是obj.name的值。

对于Animal来说,它本身也是一个对象,因此,它在访问属性和方法时也遵守上述查找规则,所以:

Animal.color -> "black"

Animal.name -> "Animal" , Animal先查找自身的name,找到了name,注意:但这个name不是我们定义的name,而是函数对象内置的属性。

一般情况下,函数对象在产生时会内置name属性并将函数名作为赋值(仅函数对象)。

Animal.say -> Animal在自身没有找到say方法,也会沿着其原型链查找,话说Animal的原型链是什么呢?

从调试结果看:Animal的原型链是这样的:

Animal->Function.prototype->Object.prototype->null

因此Animal的原型链上没有定义say方法!

总结一下,javascript的new关键字主要的作用是继承,上面例子中,cat对象在产生时便继承了Animal中定义的方法和属性,因此cat不是Animal的实例而是其子类(不严谨的说法)。可能有人还会想:cat既然是new出来的,那cat和Animal应该是同类型的。我认为既然是父类和子类的关系,那就不可能是同类型,不信,你看:

javascript 使用new关键字的区别

第一种方式使用new关键字以原型的方式将user对象暴露到window对象中

//one
var user = function(){
  this.name="";
  this.id="";
};
user.add = function(){
  console.log("add");
};
user.delete = function(){
  console.log("delete");
};
user.prototype = user;
window.user = new user();

第二种方式不使用new关键字直接将user对象暴露到window对象中

//two
var user = {
  name:"",
  id:""
};
user.add = function(){
  console.log("add");
};
user.delete = function(){
  console.log("delete");
};
window.user = user;

使用

<button onclick="user.add()">增加</button>
<button onclick="user.delete()">删除</button>
(0)

相关推荐

  • 谈谈JavaScript的New关键字

    原型和闭包算是JavaScript中最常见,最难以理解,最容易被当做问题的两个部分,当然还有它们的延伸,如作用域链,继承等等吧,我最近也是各种看,各种翻,记录点自己的心得,写写总会让自己的理解更深一些.(跟标题的关系不大啦,就感慨句,每次总感觉自己懂了,再翻还是收获满满) 先谈一下JavaScript中New关键字吧,通常我们通过它来创建一个类的实例对象,在JavaScript中,实例化对象之后,也就继承了类的属性以及方法.通过代码来演示一下 function Person(name){ thi

  • javascript 常用关键字列表集合

    Javascript关键字(Reserved Words)是指在Javascript语言中有特定含义,成为Javascript语法中一部分的那些字.Javascript关键字是不能作为变量名和函数名使用的.使用Javascript关键字作为变量名或函数名,会使Javascript在载入过程中出现编译错误. Javascript关键字列表:  break delete function return typeof  case do if switch var  catch else in this

  • Javascript this关键字使用分析

    关于js中的this关键字的文章已经不少了,我看过几篇,我写这篇文章的目的是从实例中分析出this的工作原理,希望对大家有所帮助. 一.基本的: 复制代码 代码如下: function doSomething(){ alert(this.id); } alert(window.doSomething);//证明了doSomething是属于window的 doSomething();//undefined window.onload = function(){ document.getEleme

  • Javascript new关键字的玄机 以及其它

    (接上)先看张对老手不新鲜但对菜鸟很有趣的图: What the heck is that? 简直是luan lun. new 抛开上面的图,先看看上篇文章留下的第二个问题,让我们在构造器的函数体内加点东西,看会发生什么. function A(){this.p = 1}var a = new A() 会得到如下结果: 为什么用new关键字构造出来的a,会获得p这个属性?new A()这行代码做了什么事情?根据上篇文章中Function的创建过程第4步,A这个对象会有一个Construct属性(

  • 不用构造函数(Constructor)new关键字也能实现JavaScript的面向对象

    JavaScript中的对象模型(object model)并不广为人知.我曾写过一篇关于他们的博客.之所以不被人所熟知,原因之一就是JavaScript是这些被人广泛使用的语言中唯一一个通过原型(prototype)来实现继承的.但是,我认为另一个原因就是这种对象模型非常复杂,难于解释.它为什么这么复杂并且又令人困惑呢?那是因为JavaScript试图去隐藏它传统的面向对象的特性--最终导致了它的双重人格(译者注:作者意思是JavaScript既有面向过程的特征,又有面向对象的特征). 我认为

  • 用JS将搜索的关键字高亮显示实现代码

    用JS让文章内容指定的关键字加亮 是这样的.. 现在有这些关键字:美容,生活,购物当在文章里头出现这些关键字,就把它加亮显示.. 文章是生成静态页面的,而这些关键字是能随时更新的,所以我想用JS来实现...不知道怎样来实现这样的功能啊?特此求助 复制代码 代码如下: <script language="JavaScript">function highlight(key) { var key = key.split('|'); for (var i=0; i<key.

  • 调试Javascript代码(浏览器F12及VS中debugger关键字)

    目前,常用的浏览器IE.Chrome.Firefox都有相应的脚本调试功能.作为我们.NET 阵营,学会如何在IE中调试JS就足够了,在掌握了IE中的调试方法以后,Chrome和Firefox中的调试方法也变得相当简单了. 在F12开发人员工具中进行调试 打开IE浏览器,按下F12键,就会打开开发人员工具,这是IE内置的开发人员开发工具,方便开发人员对HTML.CSS.Javascript等网页资源进行跟踪调试使用的. 如果你打开的时候没有固定在网页底部,可以点击右上角菜单栏中的按钮来完成. 我

  • js中的this关键字详解

    this是Javascript语言的一个关键字. 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.比如, 复制代码 代码如下: function test(){ this.x = 1; } 随着函数使用场合的不同,this的值会发生变化.但是有一个总的原则,那就是this指的是,调用函数的那个对象. 下面分四种情况,详细讨论this的用法. 情况一:纯粹的函数调用 这是函数的最通常用法,属于全局性调用,因此this就代表全局对象Global. 请看下面这段代码,它的运行结果是1.

  • JQuery+JS实现仿百度搜索结果中关键字变色效果

    1.源码 复制代码 代码如下: <script type="text/javascript"> $(function() { $("#btn_1").click(function() { var $keyword = $("#Text1").val() setHeightKeyWord('bbb', $keyword, 'Red', true) }); }); function setHeightKeyWord(id, keyword

  • javascript中new关键字详解

    和其他高级语言一样javascript中也有new关键字,我们以前认知的new是用来创建一个类的实例对象,但在js中万物皆是对象,为何还要new关键字呢,其实js中new关键字不是用来创建一个类的实例对象,而是用于继承. 接下来,本文将带你一起来探索JS中new的奥秘... function Animal(name){ this.name = name; } Animal.color = "black"; Animal.prototype.say = function(){ conso

  • javascript中this关键字详解

    不管学习什么知识,习惯于把自己所学习的知识列成一个list,会有助于我们理清思路,是一个很好的学习方法.强烈推荐. 以下篇幅有点长,希望读者耐心阅读. 以下内容会分为如下部分: 1.涵义 1.1:this涵义 1.2:this指向的可变性 2.使用场合 2.1:全局环境 2.2:构造函数 2.3:对象的方法 3.使用注意点 3.1:避免多层嵌套this 3.2:避免数组处理方法中的this 3.3:避免回调函数中的this 1.涵义 1.1:this涵义 在我写的一篇关于 构造函数与new关键字

  • javascript中正则表达式语法详解

    好久都没有写博客了,主要是太懒了,尤其是在阳春三月,风和日丽的日子,太阳暖暖的照在身上,真想美美的睡上一觉.就导致了这篇博客拖到现在才开始动笔,javascript的正则这一块也不是什么新的东西,主要是以前本人一遇到写正则的需求就开始头大,头疼,网上剽窃,东拼西凑,反正就是各种不适应,所以我打算系统的把正则表达式看一遍,一来是自己有所提升,这一块知识点的查漏补缺,二来是给大家分享一下.好了,下面我们直接进入主题: 正则是匹配字符串特定模式的一种表达式,官方是这样说的,但我的理解不外乎就是匹配字符

  • Java中final关键字详解

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法. 主要介绍:一.final关键字的基本用法.二.深入理解final关键字 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括成员变量和局部变量).下面就从这三个方面来了解一下final关键字的基本用法. 1.修饰类 当用final修饰一个类时,表明这个类不能

  • C/C++ 中extern关键字详解

    C/C++ 中extern关键字详解 在C/C++编程过程中,经常会进行变量和函数的声明和定义,各个模块间共用同一个全局变量时,此时extern就派上用场了. 定义 extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义,不需要分配内存,直接使用. 推荐:在.h中声明,因为在头文件定义的话,其他模块include此头文件,就会报重复定义错误 实验结论 1.在.h中声明 extern int g_a; 在.c中定义 int g_

  • Java中Volatile关键字详解及代码示例

    一.基本概念 先补充一下概念:Java内存模型中的可见性.原子性和有序性. 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情.为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制. 可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的.也就是一个线程修改的结果.另一个线程马上就能看到.比如:用volatile修饰的变量,就会具有可见性.volatile修饰的

  • Java中final关键字详解及实例

    final在Java中可以声明成员变量.方法.类以及本地变量.一旦你将引用声明作final,你将不能改变这个引用了,如果你试图将变量再次初始化的话,编译器会报编译错误.  final的含义在不同的场景下有细微的差别,但总体来说,它指的是"不可变". 1. final变量 凡是对成员变量或者本地变量(在方法中的或者代码块中的变量称为本地变量)声明为final的都叫作final变量.final变量经常和static关键字一起使用,作为常量.用final关键字修饰的变量,只能进行一次赋值操作

  • javascript中Promise使用详解

    目录 一.首先,要知道为什么要用Promise语法? 二.接着,来了解一下回调地狱(Callback Hell) 三.最后,也是本章的重头戏,Promise的基本使用 (一) resolve函数 (二) rejected函数 (三)Promise的API 1. then 2. catch 3. finally 4. Promise.all 5. Promise.race 四.最后 前言: 做过前端开发的都知道,JavaScript是单线程语言,浏览器只分配给JS一个主线程,用来执行任务,但是每次

  • javascript中this指向详解

    JavaScript 是一种脚本语言,支持函数式编程.闭包.基于原型的继承等高级功能.JavaScript一开始看起来感觉会很容易入门,但是随着使用的深入,你会发JavaScript其实很难掌握,有些基本概念让人匪夷所思.其中JavaScript 中的 this 关键字,就是一个比较容易混乱的概念,在不同的场景下,this会化身不同的对象.有一种观点认为,只有正确掌握了 JavaScript 中的 this 关键字,才算是迈入了 JavaScript 这门语言的门槛.在主流的面向对象的语言中(例

  • javascript的this关键字详解

    this 的定义 表示当前执行代码的环境对象 因此可将 this 的剖析分为"全局环境" 和 "函数环境" 两种类型的环境对象 全局环境 console.log(this === window); // true var a = 10; console.log(this.a); // 10 函数环境 在函数内部,this 的取值取决于函数被调用时的运行环境. 这里涉及到内存里的数据结构相关的知识点,当我们定义以下字面量对象时会发生一系列的关联关系 var obj =

随机推荐