第 100 题:请写出如下代码的打印结果

发布于 2022-08-12 12:15:58 字数 297 浏览 133 评论 36

function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
Foo.prototype.a = function() {
    console.log(3)
}
Foo.a = function() {
    console.log(4)
}
Foo.a();
let obj = new Foo();
obj.a();
Foo.a();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(36

南…巷孤猫 2022-05-04 13:55:37

421

燕归巢 2022-05-04 13:55:37
// 构造函数Foo
function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
// 在构造函数Foo的原型上添加a方法
Foo.prototype.a = function() {
    console.log(3)
}
// 在构造函数Foo上添加a方法
Foo.a = function() {
    console.log(4)
}
// 直接调用Foo.a()方法
Foo.a();
// 实例化, 会执行构造函数
// 实例化所在事情:在Foo上添加a方法,在新建实例上添加a方法,在Foo的原型上添加a方法
let obj = new Foo();
//执行Foo的实例obj的方法a
obj.a();
// 执行Foo的方法a
Foo.a();
魔法少女 2022-05-04 13:55:37
function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
Foo.prototype.a = function() {
    console.log(3)
}
Foo.a = function() {
    console.log(4)
}
Foo.a(); // 调用构造函数的自身的方法 ,所以结果是4
let obj = new Foo(); // new重新创建一个obj,使它指向Foo,拥有了构造函数的属性和方法
obj.a();  //  因为构造函数有直接方法,所以输出2
Foo.a();  // 构造函数重新全局a方法,所以结果结果是1,之前是4

// 结果是4、2、1
左岸枫 2022-05-04 13:55:37
// 构造函数Foo
function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
// 在构造函数Foo的原型上添加a方法
Foo.prototype.a = function() {
    console.log(3)
}
// 在构造函数Foo上添加a方法
Foo.a = function() {
    console.log(4)
}
// 直接调用Foo.a()方法
Foo.a();
// 实例化, 会执行构造函数
// 实例化所在事情:在Foo上添加a方法,在新建实例上添加a方法,在Foo的原型上添加a方法
let obj = new Foo();
//执行Foo的实例obj的方法a
obj.a();
// 执行Foo的方法a  (Foo经过上一步实例化之后,重新绑定了a方法)
Foo.a();
熊抱啵儿 2022-05-04 13:55:37

4
2
1

朦胧时间 2022-05-04 13:55:37

这个我会,来声个张,

终难遇 2022-05-04 13:55:37

421~
声明顺序:
Foo.a = function() { console.log(4) }
所以第一个为4,

接下来new了一下构造函数~
虽然把原型链挂到了新obj,
但是,构造函数重定义了Foo.a,且设定构造函数的娃的a为2。

野心澎湃 2022-05-04 13:55:37

2楼的解完美
补一句,
function Foo() { Foo.a = function() { console.log(1) } //this.a = function() {//干掉这里 让prototype上a,console出3可以生效的方法 //console.log(2) //} } Foo.prototype.a = function() { console.log(3) } Foo.a = function() { console.log(4) } Foo.a(); let obj = new Foo(); obj.a(); Foo.a();

孤单情人 2022-05-04 13:55:37

`Foo.a(); // 4 全局的Foo.a

let obj = new Foo(); // 执行Foo的构造函数,将 最后的 Foo.a(全局)覆盖

obj.a(); // 2 this.a

Foo.a(); // 1 Foo构造函数里的 foo.a 因为全局的已经被覆盖
`

-时光礼记 2022-05-04 13:55:37

京东怎么总喜欢出这种乱七八糟的题

末蓝 2022-05-04 13:55:37

421
大家回答挺好的,考察的是原型链和实例的问题

 function Foo() {
   Foo.a = function() {
     console.log(1);
   };
   this.a = function() {
     console.log(2);
   };
}
 
// 原型方法,在生成实例时使用
 Foo.prototype.a = function() {
   console.log(3);
};
 
// 静态方法,可以直接调用
 Foo.a = function() {
   console.log(4);
};
 
 Foo.a(); // 实例没有生成,直接调用静态方法,输出4
 let obj = new Foo();
 obj.a(); // 实例中有a,不去原型链中查找,之前在Foo.prototype.a的函数也被覆盖,输出2
 Foo.a(); // 生成实例后,Foo原型链中的静态方法被覆盖,输出1
巷子口的你 2022-05-04 13:55:37

这道题很好的讲述了构造函数中,new做的事情:
(1)创建一个新对象;
(2)将构造函数的作用域赋给新对象(因此this就指向了这个对象);所以,obj.a()输出2
(3)执行构造函数中的代码(为这个新对象添加属性); 所以Foo.a()输出1,因为被覆盖了
(4)返回新对象。

等风来 2022-05-04 13:55:37

function Foo() { Foo.a = function() { console.log(1) } this.a = function() { console.log(2) } }
该步骤是函数声明,函数声明会被编译器优先进行提升,并且在全局(此题为全局)词法作用域中声明了叫Foo的标识符。

Foo.prototype.a = function() { console.log(3) }
在函数原型上添加了一个a函数
Foo.a = function() { console.log(4) }

在Foo上添加了一个a函数,js中万物皆函数,所以就相当于在Foo这个对象上添加了一个新的属性a,并赋值为一个函数。要注意的是,这并不会对Foo构造(new)出来的对象造成影响。

Foo.a() 执行了上面定义的函数 console.log(4)

let obj = new Foo();

new 相当于创建一个新对象,用Foo对其进行构造,题目中Foo中对obj有影响的只有this.a = ...

obj的__proto__也会指向其构造函数Foo的原型Foo.prototype

所以当obj中查找的属性不存在时,顺着__proto__到Foo.prototype中去找,还找不到就去Object.prototype中找。

同样Foo(),说明Foo被执行了一次。
在Foo中
”Foo.a = function() {
console.log(1)
}“
这段代码首先会在Foo的作用域中寻找是否存在Foo这个标识符,若存在,会将其属性a定义。若不存在,会查找父作用域中是否存在。所以Foo.其实改的是父作用域的Foo,因为函数内部不存在这个值的。
所以这段代码,在本题目中,其实写在哪都一样。

obj.a();

由于obj自身拥有a,所以会执行console.log(2)
Foo.a();

再此执行全局作用域中的Foo.a 因为Foo()执行了对Foo.a的修改,所以console.log(1)`

简单爱 2022-05-04 13:55:37

思路:

function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
Foo.prototype.a = function() {
    console.log(3)
}
Foo.a = function() {
    console.log(4)
}
Foo.a();   //由于Foo未初始化,所有不会执行构造函数中代码,所有调用的是外面的Foo.a,输出4
let obj = new Foo();   // 执行构造函数,`this.a`被执行
obj.a(); // 由于在Foo构造函数中存在`this.a`,所以此时不会向上查找原型链上的a函数,执行`this.a`中代码
Foo.a();  // 构造函数被执行,Foo.a被新的代码覆盖,此时Foo.a为构造函数内部的赋值,输出1

结果:4,2,1

寻鱼水之欢 2022-05-04 13:55:37

100题达成 前面又忘了(bushi)。。。

半衾梦 2022-05-04 13:55:37

打印顺序 4 2 1

function Foo() {

    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
// 给Foo类的实例的原型增加名为a的属性,打印3
Foo.prototype.a = function() {
    console.log(3)
}
// 给Foo对象增加一个名为a的属性,打印4
Foo.a = function() {
    console.log(4)
}
// 调用Foo对象的a方法,输出4
Foo.a();
// 实例化Foo类为obj对象,此时Foo构造函数被调用
// Foo对象的a属性被替换为打印1的函数
// 实例方法a被赋值为一个打印2的函数
let obj = new Foo();
obj.a(); // 2
Foo.a(); //1
嘿嘿嘿 2022-05-04 13:55:37

function Foo() {
Foo.a = function() {
console.log(1)
} //静态方法
this.a = function() {
console.log(2)
}
}
Foo.prototype.a = function() {
console.log(3)
}
以上函数里面的方法,属性,原型链上的方法,属性只有实例对象才可以访问到
Foo.a = function() {
console.log(4)
}//静态方法
Foo.a(); //直接访问静态方法
let obj = new Foo(); //创建实例对象,这时候对象可以访问 原型链上的属性和方法,以及构造函数的属性和方法
obj.a(); //访问规则:先查好构造函数中是否有,没有在查看原型链中是否有
Foo.a(); //执行构造函数的时修改了静态方法
最总:4 2 1

任性一次 2022-05-04 13:55:36

答案为:4, 2, 1
解析:

  1. Foo.a() 这个是调用 Foo 函数的静态方法 a,虽然 Foo 中有优先级更高的属性方法 a,但 Foo 此时没有被调用,所以此时输出 Foo 的静态方法 a 的结果:4
  2. let obj = new Foo(); 使用了 new 方法调用了函数,返回了函数实例对象,此时 Foo 函数内部的属性方法初始化,原型方法建立。
  3. obj.a(); 调用 obj 实例上的方法 a,该实例上目前有两个 a 方法:一个是内部属性方法,另一个是原型方法。当这两者重名时,前者的优先级更高,会覆盖后者,所以输出:2
  4. Foo.a(); 根据第2步可知 Foo 函数内部的属性方法已初始化,覆盖了同名的静态方法,所以输出:1
聚集的泪 2022-05-04 13:55:36

421

嘿,哥们儿 2022-05-04 13:55:22

// 定义一个构造函数Foo
function Foo() {
Foo.a = function() {
console.log(1)
}
this.a = function() {
console.log(2)
}
}
// 给构造函数Foo的原型对象上添加属性a
Foo.prototype.a = function() {
console.log(3)
}
// 函数也是对象,给Foo函数添加属性a
Foo.a = function() {
console.log(4)
}
// 访问Foo函数上的属性a执行 ,输出 4
Foo.a();
// 实例化出对象obj,在new的过程中,给Foo上的a重新赋值,实例化出的obj对象也有一个a
let obj = new Foo();
// 输出 2
obj.a();
// 输出1
Foo.a();

給妳壹絲溫柔 2022-05-04 13:55:16

那些只说结果不去分析的,有啥意义。。

想你的星星会说话 2022-05-04 13:52:51
function Foo() { // 构造函数Foo
  Foo.a = function() {
    console.log(1)
  }
  this.a = function() {
    console.log(2)
  }
}
Foo.prototype.a = function() { // 原型上也有个a属性
  console.log(3)
}
Foo.a = function() { // 未new时,给函数对象添加a方法
  console.log(4)
}
Foo.a();  // 很自然这里打印的是 4 
let obj = new Foo(); // 实例化一个obj对象 ,执行了一次Foo函数
// 原型链
obj.__proto__ === Foo.prototype
Foo.prototype.__proto__ === Object.prototype
Object.prototype === null
obj.a(); // 2
Foo.a(); // 1
树深时见影 2022-05-04 13:52:51

function Foo() {
Foo.a = function() {
console.log(1)
}
this.a = function() {
console.log(2)
}
}
Foo.prototype.a = function() {
console.log(3)
}
Foo.a = function() {
console.log(4)
}
Foo.a(); //4
let obj = new Foo(); //
obj.a(); //2
Foo.a(); //1

姐不稀罕 2022-05-04 13:45:31
function Foo() {
    Foo.a = function() {
      console.log(1)
    }
    this.a = function() {
      console.log(2)
    }
}
// 实例方法
Foo.prototype.a = function() {
   console.log(3)
}
// 静态方法
Foo.a = function() {
   console.log(4)
}
Foo.a(); // 4  直接调Foo静态方法a
let obj = new Foo();
obj.a(); // 2  因是obj调用,故优先调用构造函数Foo自身的方法a,如果自身没有则执行原型链上的方法a
Foo.a(); // 1  因执行了一次new 操作,故再次调用Foo.a()时调用了Foo函数体内的静态方法a
昨迟人 2022-05-04 13:43:05

4,2,1

心凉 2022-05-04 13:41:32

4,2,1

风轻花落早 2022-05-04 13:40:44
function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
Foo.prototype.a = function() {
    console.log(3)
}
Foo.a = function() {
    console.log(4)
}
Foo.a();
let obj = new Foo();
obj.a();
Foo.a();

答案:

4、2、1

  Foo.a() 第一个为4没有什么异议
  new 的时候会将函数的主函数执行一遍,并将原型挂载至新的函数上,此时obj有本身来自Foo的this.a,也有原型上的prototype.a,查找obj.a时,在函数本域上有this.a,则直接输出来自于Foo的this.a,也就是console.log(2)。接下来的Foo.a,这时候Foo函数内部由于同样有Foo.a = function ...,new的时候Foo.a的值相当于被重置了,则输出1。

薄暮涼年 2022-05-04 13:39:45

输出顺序:4,2,1

机场等船 2022-05-04 13:34:14

4 2 1

拿命拼未来 2022-05-04 13:04:48

4 2 1

開玄 2022-05-04 11:56:38

421

  • 考察的应该是原型和函数的理解
零崎曲识 2022-05-04 08:40:27

4 2 1

听风念你 2022-05-04 03:39:49

4 2 1

柠檬心 2022-05-03 21:53:27

输出顺序是 4 2 1 .

function Foo() {
    Foo.a = function() {
        console.log(1)
    }
    this.a = function() {
        console.log(2)
    }
}
// 以上只是 Foo 的构建方法,没有产生实例,此刻也没有执行

Foo.prototype.a = function() {
    console.log(3)
}
// 现在在 Foo 上挂载了原型方法 a ,方法输出值为 3

Foo.a = function() {
    console.log(4)
}
// 现在在 Foo 上挂载了直接方法 a ,输出值为 4

Foo.a();
// 立刻执行了 Foo 上的 a 方法,也就是刚刚定义的,所以
// # 输出 4

let obj = new Foo();
/* 这里调用了 Foo 的构建方法。Foo 的构建方法主要做了两件事:
1. 将全局的 Foo 上的直接方法 a 替换为一个输出 1 的方法。
2. 在新对象上挂载直接方法 a ,输出值为 2。
*/

obj.a();
// 因为有直接方法 a ,不需要去访问原型链,所以使用的是构建方法里所定义的 this.a,
// # 输出 2

Foo.a();
// 构建方法里已经替换了全局 Foo 上的 a 方法,所以
// # 输出 1
时光与爱终年不遇 2022-05-03 15:49:57

结果如下

4
2
1
~没有更多了~

关于作者

0 文章
0 评论
22 人气
更多

推荐作者

内心激荡

文章 0 评论 0

JSmiles

文章 0 评论 0

左秋

文章 0 评论 0

迪街小绵羊

文章 0 评论 0

瞳孔里扚悲伤

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文