记Javascript一道题的理解

代码如下:

function Foo(){
    getName = function(){ console.log("1"); }
    return this;
}
Foo.getName = function(){
    console.log("2");
}
Foo.prototype.getName = function(){
    console.log("3");
}
var getName = function(){
    console.log("4");
}
function getName(){
    console.log("5");
}
Foo.getName(); //2
getName(); //4
Foo().getName(); //1
getName(); //1
new Foo.getName(); //2 => new (Foo.getName)() new无参数列表
new Foo().getName(); // 3 => (new Foo()).getName(); //new有参数列表
new new Foo().getName(); //3 => new ((new Foo()).getName)() //new有参数列表

Foo.getName()

输出结果为:2
原理:他调用的是Foo的静态方法(如果C#、java等后端语言来说),其实是因为Javascript中的Function本身就是Function和Object的结合,所以function既是函数,也是对象。在这里Foo就是执行了他对象上的一个function而已。

getName()

输出结果为:4
原理:可能你会想为什么不是5,function变量会提升到作用域的顶部,而var定义的则不会,所以var声明的覆盖掉function声明。所以结果为4

Foo().getName()

输出结果为:1
原理:Foo()是函数调用,Foo执行体中对getName进行了重新赋值(全局的getName,根据作用域链向上查找),返回的this为window(Foo执行时没有调用,默认为全局),然后.getName()调用了全局的getName(也就是被Foo执行体重写的getName),所以结果为:1

getName()

输出结果为:1 原理:因为Foo执行体中对全局getName重写了,这时调用的又是全局的getName。所以结果为:1

new Foo.getName()

输出结果为:2
原理:

  • 由于new无参,与new有参的运算优化级一样。new有参的与.运算符同一级别,而new无参的低一个级别。所以会先执行.运算符选择到Foo的静态方法getName
  • 然后执行new,获得的是Foo.getName的一个实例。所以输出结果为:2

new Foo().getName()

输出结果为:3

原理:

  • 由于new是有参的,与.运算符同级,按照从左向右的执行顺序,先执行new Foo()。
  • new Foo()是需要值得我们的注意,因为他有一个返回值。存在返回值分为两种情况:
    • 无返回与返回为基本类型是一样的效果:返回都是实例对象(也就是当前的this)
    • 返回为引用类型:返回的为这个引用类型的对象,此时实例对象被替换了(也就是当前的this没有返回)。因数new Foo()返回是实例对象
  • .getName():选择是上一步实例的此方法,所以输出结果为:3

new new Foo().getName()

输出结果为:3
原理:主要是运算符优先级的考查,实例开发中应该不会这样直接的用到。首先new有参,然后.getName(.运算符)(为什么是.运算符,这是因为new无参级别低一个档次),再则new有参。

时间: 2024-08-06 07:58:01

记Javascript一道题的理解的相关文章

JavaScript 模块化入门Ⅰ:理解模块

作为一名JS初学者.假如你听到了一些诸如"模块化构建&模块化载入" "Webpack&Browserify" 或者 "AMD&CMD"之类的术语,肯定瞬间就凌乱了. JavaScript的模块化听起来挺深奥,可其实理解它对开发者来说特别实用. 在这篇文章里,我会尽量深入浅出地把这些深奥的术语翻译成浅显易懂的人话(加上一些代码示例).希望你多少能从中学到点东西. 为了避免长篇大论,整个内容会分为两篇文章,这是第一部分,主要介

javascript this的范围理解

<html> <head> <title>javascript this的范围理解</title> </head> <body> <script type="text/javascript"> //在javascript中,函数总是在一个特殊的上下文执行(称为执行上下文),如果你将一个对象的函数赋值给另外一个变量的话,这个函数的执行上下文就变为这个变量的上下文了 window.name = "

第二话:javascript中闭包的理解

闭包是什么? 通过闭包,子函数得以访问父函数的上下文环境,即使父函数已经结束执行. OK,我来简单叙述下,先上图. 都知道函数是javascript整个世界,对象是函数,方法是函数,并且js中实质性的面向对象相关也都是函数来实现和延伸,例如:"类". window:是指js中window类,也是js最高一层,因为什么这么说,因为你所有创建的方法和属性其实都在window之内.window中的所有方法,在自己创建的方法中都可以调到.可以仔细想想alert,在任何地方都可以alert,其实

03.JavaScript 面向对象精要--理解对象

JavaScript 面向对象精要--理解对象 尽管JavaScript里有大量内建引用类型,很可能你还是会频繁的创建自己的对象.JavaScript中的对象是动态的. 一.定义属性 当一个属性第1次被添加给对象时JavaScript在对上上调用了一个名为 [[Put]]的内部方法,该方法会在对象上创建一个新节点保存属性,就像 哈希表上第一次添加一个键一样这个操作不仅指定了初始值 也定义了属性的一些特征 1.1 [[Put]]内部方法 [[Put]]在对象上创建一个自有属性 1.2 [[Set]

Javascript对于类型的理解

1.instanceof和typeof区别 两者都是用来判断类型用的,instanceof顾名思义,是否是某一类型的实例,这个返回值是bool值,例如(new String("so") instanceof String) typeof返回值则是类型名,如(typeof 'so') Javascript对于类型的理解

Javascript中Function declarations 理解

首先来看一段代码: 1.f = function() {return true;}; 2.g = function() {return false;}; 3.(function() { 4. if (g() && [] == ![]) { 5. f = function f() {return false;}; 6. function g() {return true;} 7. } 8.})(); 9.console.log(f()); 理解上面这段code有几个关键点: 第4行code的

对JavaScript闭包和原型理解

最近在学js脚本的一些东西觉得里面有2个知识点比较难理解所以做了如下总结. 1.闭包 简单的理解:一个函数a ,内部有个函数b,那么这个函数b当被作为a函数的返回值得时候被外部的全局变量引用了,那么这就是一个闭包. 官方解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 如: a=function() { var n=1; b=function( n=n+1; alert(n) } return b; } var c=a()aler

记JavaScript的入门学习(二)

2016年11月25号,利用上午时间学习了JavaScript的数据类型和变量,下午就该去图书馆泡书了. 看完变量的本章节,发现我可能不能一天结束,那我就利用上午和晚上九点回来的时间完成吧.把心态调整好,不求速度,只求质量,学会即可,也许我就是下一个Js大神/偷笑/偷笑/偷笑 2.1    并得到如下小实例: 代码解释: 2.1.1  var myFirstVariable;此时变量的值是undefined,对于计算机而言,变量声明仅仅表明了变量的存在,并没有在其中保存任何实际的数据,但是und

JavaScript基础知识逐步理解。

浅谈JavaScript入门基础:    在对JavaScript的内容进行深入研究前,我对JavaScript的基础方面进行一次系统性的整理,下面把这些知识分享给大家.1 JavaScript的组成:    ECMAScript:解释器--将人类可读可解的语言与计算机语言进行交互,方便计算机运行,方便人类读解.    DOM:Document Object Modle.--通过DOM对HTML进行操作.    BOM:Browser Object Modle.--通过BOM来对浏览器窗口进行操