Coding题: 1. 预测以下代码的输出结果:
  1. var Foo = function(a) {
  2. function bar() {
  3. console.log(a);
  4. };
  5. this.baz = function() {
  6. console.log(a);
  7. };
  8. };
  9.  
  10. Foo.prototype = {
  11. biz: function() {
  12. console.log(a);
  13. }
  14. };
  15.  
  16. var f = new Foo(7);
  17. //预测输出结果:
  18. f.bar(); // result: TypeError, f.bar is not a function.
  19. f.baz(); // result: 7
  20. f.biz(); // result: ReferenceError, a is not defined

2、

  1. // 函数声明语句
  1. {
  2. let a = 'secret';
  3. function f() {
  4. return a;
  5. }
  6. }

  1. // 函数表达式
  1. {
  2. let a = 'secret';
  3. let f = function () {
  4. return a;
  5. };
  6. }

3、闭包

  https://www.cnblogs.com/lulin1/p/7324435.html

  1. var x = ;
  2. function foo() {
  3. alert(x);
  4. }
  5. (function (funArg) {
  6. var x = ; // 变量"x"在foo中静态保存的,在该函数创建的时候就保存了 如果是x=20输出20
  7. funArg(); // 10, 而不是20
  8. })(foo);

4、闭包

  1. var firstClosure;
  2. var secondClosure;
  3.  
  4. function foo() {
  5.  
  6. var x = ;
  7.  
  8. firstClosure = function () { return ++x; };
  9. secondClosure = function () { return --x; };
  10.  
  11. x = ; // 影响"x", 在2个闭包公有的[[Scope]]中
  12.  
  13. alert(firstClosure()); // 21, 通过第一个闭包的[[Scope]]
  14. }
  15.  
  16. foo();
  17.  
  18. alert(firstClosure()); //
  19. alert(secondClosure()); //

5、ES6函数作用域

  1. var x = 1;
  2. function foo(x, y = function() { x = 2; }) {
  3. var x = 3;
  4. y();
  5. console.log(x);
  6. }
  7.  
  8. foo() //
  9. x //
  1. var x = 1;
  2. function foo(x, y = function() { x = 2; }) {
  3. x = 3;
  4. y();
  5. console.log(x);
  6. }
  7.  
  8. foo() //
  9. x //

  

  上面代码中,函数foo的参数形成一个单独作用域。这个作用域里面,首先声明了变量x,然后声明了变量yy的默认值是一个匿名函数。这个匿名函数内部的变量x,指向同一个作用域的第一个参数x。函数foo内部又声明了一个内部变量x,该变量与第一个参数x由于不是同一个作用域,所以不是同一个变量,因此执行y后,内部变量x和外部全局变量x的值都没变。

  如果将var x = 3var去除,函数foo的内部变量x就指向第一个参数x,与匿名函数内部的x是一致的,所以最后输出的就是2,而外层的全局变量x依然不受影响。

  1. function foo() {
  2. console.log(this.a)
  3. }
  4. var a = 1
  5. foo()
  6.  
  7. var obj = {
  8. a: 2,
  9. foo: foo
  10. }
  11. obj.foo()

  比较没有 this 的情况:

  1. function foo() {
  2. console.log(a)
  3. }
  4. var a = 1
  5. foo()
  6.  
  7. var obj = {
  8. a: 2,
  9. foo: foo
  10. }
  11. obj.foo()

  

6、ES6箭头函数

  1. function foo() {
  2. console.log('id:', this.id);
  3. }
  4.  
  5. var id = 21;
  6.  
  7. foo.call({ id: 42 }); // id : 42
  1. var foo = () => {
  2. console.log('id:', this.id);
  3. }
  4.  
  5. var id = 21;
  6.  
  7. foo.call({ id: 42 }); // id: 21
  1. function foo() {
  2. setTimeout(function() {
  3. console.log('id:', this.id);
  4. }, 100);
  5. }
  6.  
  7. var id = 21;
  8.  
  9. foo.call({ id: 42 }); // id : 21
  1. function foo() {
  2. setTimeout(() => {
  3. console.log('id:', this.id);
  4. }, 100);
  5. }
  6.  
  7. var id = 21;
  8.  
  9. foo.call({ id: 42 }); // id : 42 箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),所以输出的是42

7、ES6箭头函数

  1. function Timer() {
  2. this.s1 = 0;
  3. this.s2 = 0;
  4. // 箭头函数
  5. setInterval(() => this.s1++, 1000);
  6. // 普通函数
  7. setInterval(function () {
  8. this.s2++;
  9. }, 1000);
  10. }
  11.  
  12. var timer = new Timer();
  13.  
  14. setTimeout(() => console.log('s1: ', timer.s1), 3100);
  15. setTimeout(() => console.log('s2: ', timer.s2), 3100);
  16. // s1: 3
  17. // s2: 0

  上面代码中,Timer函数内部设置了两个定时器,分别使用了箭头函数和普通函数。前者的this绑定定义时所在的作用域(即Timer函数),后者的this指向运行时所在的作用域(即全局对象)。所以,3100 毫秒之后,timer.s1被更新了 3 次,而timer.s2一次都没更新。

8、ES6箭头函数

  请问下面的代码之中有几个this

  1. function foo() {
  2. return () => {
  3. return () => {
  4. return () => {
  5. console.log('id:', this.id);
  6. };
  7. };
  8. };
  9. }
  10.  
  11. var f = foo.call({id: 1});
  12.  
  13. var t1 = f.call({id: 2})()(); // id: 1
  14. var t2 = f().call({id: 3})(); // id: 1
  15. var t3 = f()().call({id: 4}); // id: 1

  上面代码之中,只有一个this,就是函数foothis,所以t1t2t3都输出同样的结果。因为所有的内层函数都是箭头函数,都没有自己的this,它们的this其实都是最外层foo函数的this

9、即时函数执行过程

  1. var result = (function(){
  2. return 1;
  3. },function(){
  4. return "2"
  5. },function(){
  6. return "3"
  7. })()
  8.  
  9. console.log(typeof result) // string
  10. console.log( result) //

  从右向左执行,并只执行一次就结束。

10、执行上下文

  我们先看个简单的例子:

  1. var t = function() {
  2. var n = 99;
  3. var t2 = function() {
  4. n++
  5. console.log(n)
  6. }
  7. return t2;
  8. };
  9.  
  10. var a1 = t();
  11. var a2 = t();
  12.  
  13. a1(); // 100
  14. a1(); // 101
  15.  
  16. a2(); // 100
  17. a2(); // 101

  

  我们会发现,n 的值都是从 99 开始,执行 一次a1() 的时候,值会加一,再执行一次,值再加一,但是 n 在 a1() 和 a2() 并不是公用的。你可以理解为:同一个函数形成的多个闭包的值都是相互独立的。

  接下来看这道题目,关键在于 nAdd 函数。

  1. var nAdd;
  2. var t = function() {
  3. var n = 99;
  4. nAdd = function() {
  5. n++;
  6. }
  7. var t2 = function() {
  8. console.log(n)
  9. }
  10. return t2;
  11. };
  12.  
  13. var a1 = t();
  14. var a2 = t();
  15.  
  16. nAdd();
  17.  
  18. a1(); //99
  19. a2(); //100

  当执行 var a1 = t()的时候,变量 nAdd 被赋值为一个函数 ,这个函数是function (){n++},我们命名这个匿名函数为 fn1 吧。接着执行 var a = t()的时候,变量 nAdd 又被重写了,这个函数跟以前的函数长得一模一样,也是function (){n++},但是这已经是一个新的函数了,我们就命名为 fn2 吧。

  所以当执行 nAdd 函数,我们执行的是其实是 fn2,而不是 fn1,我们更改的是 a2 形成的闭包里的 n 的值,并没有更改 a1 形成的闭包里的 n 的值。所以 a1() 的结果为 99 ,a2()的结果为 100。

11、执行上下文+闭包

A:

  1. var scope = "global scope";
  2. function checkscope(){
  3. var scope = "local scope";
  4. function f(){
  5. return scope;
  6. }
  7. return f();
  8. }
  9. checkscope(); // local scope

B:

  1. var scope = "global scope";
  2. function checkscope(){
  3. var scope = "local scope";
  4. function f(){
  5. return scope;
  6. }
  7. return f;
  8. }
  9. checkscope()(); // local scope

  两段代码都会打印'local scope'。虽然两段代码执行的结果一样,但是两段代码究竟有哪些不同呢?

  如果你理解了A的执行流程,那么B的流程在细节上一致,唯一的区别在于B的环境栈变化不一样,

    A: contextStack = [globalContext] ---> contextStack = [checkscopeContext, globalContext] ---> contextStack = [fContext, checkscopeContext, globalContext] ---> contextStack = [checkscopeContext, globalContext] ---> contextStack = [globalContext]

    B: contextStack = [globalContext] ---> contextStack = [checkscopeContext, globalContext] ---> contextStack = [fContext, globalContext] ---> contextStack = [globalContext]

  也就是说,真要说这两段代码有啥不同,那就是他们执行过程中环境栈的变化不一样,其他的两种方式都一样。

  其实对于理解这两段代码而言最根本的一点在于,javascript是使用静态作用域的语言,他的作用域在函数创建的时候便已经确定(不含arguments)。

12、闭包

  刷题必刷,面试必考的闭包题:

  1. var data = [];
  2.  
  3. for (var i = 0; i < 3; i++) {
  4. data[i] = function () {
  5. console.log(i);
  6. };
  7. }
  8.  
  9. data[0](); //3
  10. data[1](); //3
  11. data[2](); //3

  让我们改成闭包看看:

  1. var data = [];
  2.  
  3. for (var i = 0; i < 3; i++) {
  4. data[i] = (function (i) {
  5. return function(){
  6. console.log(i);
  7. }
  8. })(i);
  9. }
  10.  
  11. data[0](); //0
  12. data[1](); //1
  13. data[2](); //2

  使用let定义后:

  1. var data = [];
  2.  
  3. for (let i = 0; i < 3; i++) {
  4. data[i] = function () {
  5. console.log(i);
  6. };
  7. }
  8.  
  9. data[0](); //0
  10. data[1](); //1
  11. data[2](); //2

参考:

13、参数传递(按值传递 || 共享传递)  

  (1)按值传递

  1. var value = 1;
  2. function foo(v) {
  3. v = 2;
  4. console.log(v); //2
  5. }
  6. foo(value);
  7. console.log(value) // 1

  (2)共享传递

  1. var obj = {
  2. value: 1
  3. };
  4. function foo(o) {
  5. o.value = 2;
  6. console.log(o.value); //2
  7. }
  8. foo(obj);
  9. console.log(obj.value) // 2

  

  1. var obj = {
  2. value: 1
  3. };
  4. function foo(o) {
  5. o = 2;
  6. console.log(o); //2
  7. }
  8. foo(obj);
  9. console.log(obj.value) // 1

  共享传递是指,在传递对象的时候,传递对象的引用的副本。

  所以修改 o.value,可以通过引用找到原值,但是直接修改 o,并不会修改原值。所以这两个例子其实都是按共享传递。

14、变量对象(VO)

(1)

  1. function foo() {
  2. console.log(a);
  3. a = 1;
  4. }
  5.  
  6. foo(); // ???
  7.  
  8. function bar() {
  9. a = 1;
  10. console.log(a);
  11. }
  12. bar(); // ???  

  第一段会报错:Uncaught ReferenceError: a is not defined

  第二段会打印:1

  这是因为函数中的 "a" 并没有通过 var 关键字声明,所有不会被存放在 AO 中。

  第一段执行 console 的时候, AO 的值是:

  1. AO = {
  2. arguments: {
  3. length: 0
  4. }
  5. }

  没有 a 的值,然后就会到全局去找,全局也没有,所以会报错。

  当第二段执行 console 的时候,全局对象已经被赋予了 a 属性,这时候就可以从全局找到 a 的值,所以会打印 1。

(2)

  1. console.log(foo);
  2.  
  3. function foo(){
  4. console.log("foo");
  5. }
  6.  
  7. var foo = 1;

  会打印函数,而不是 undefined 。

  这是因为在进入执行上下文时,首先会处理函数声明,其次会处理变量声明,如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性。

 

Js 编程题汇总的更多相关文章

  1. JS编程题练习

    JS编程题练习 1. 两个数组合并成一个数组排序返回 先依次比较两个数组,按照小的就传入新的数组.当这次比较完之后可能有一个数组的长度很长,留下一些数组,然后在新数组的末尾插入即可. function ...

  2. JS编程题

    1.计算给定数组 arr 中所有元素的总和 (数组中的元素均为 Number 类型) function sum(arr) { var sum=0; for (var i=arr.length-1; i ...

  3. 拼多多2018校招编程题汇总 Python实现

    题目原址 列表补全 在商城的某个位置有一个商品列表,该列表是由L1.L2两个子列表拼接而成.当用户浏览并翻页时,需要从列表L1.L2中获取商品进行展示.展示规则如下: 用户可以进行多次翻页,用offs ...

  4. 五四青年节,今天要学习。汇总5道难度不高但可能遇到的JS手写编程题

    壹 ❀ 引 时间一晃,今天已是五一假期最后一天了,没有出门,没有太多惊喜与意外.今天五四青年节,脑子里突然想起鲁迅先生以及悲欢并不相通的话,我的五一经历了什么呢,忍不住想说那大概是,父母教育孩子大声嚷 ...

  5. 50道经典的JAVA编程题(汇总)

    这是一次不可思议的编程历程.从2013年的最后一天开始做这份题,中间连续好几天的考试,包括java考试(今天考试的JAVA编程题),直到今天完成了.挺有成就感的...废话不多说了,来电实质性的吧. 全 ...

  6. 数据可视化的优秀入门书籍有哪些,D3.js 学习资源汇总

    习·D3.js 学习资源汇总 除了D3.js自身以外,许多可视化工具包都是基于D3开发的,所以对D3的学习就显得很重要了,当然如果已经有了Javascript的经验,学起来也会不费力些. Github ...

  7. 去哪儿网2017校招在线笔试(前端工程师)编程题及JavaScript代码

    编程题很简单.整个试卷结构为: 一.问答题: 对前端的理解,了解哪些框架库? 二.在线编程题:身份证分组 如下第一道:身份证分组 三.在线编程题:身份证分组.统计字符.酒店价格(三选二) 如下第二三四 ...

  8. 《C语言程序设计》编程总结汇总

    <C语言程序设计>编程总结汇总 院系: 专业年级: 班级名称: 学号: 姓名: 指导教师: 完成时间: 自我评价: 计算机科学与技术专业教研室 2018 年秋季学期 第四周编程总结 题目4 ...

  9. 算法是什么我记不住,But i do it my way. 解一道滴滴出行秋招编程题。

    只因在今日头条刷到一篇文章,我就这样伤害我自己,手贱. 刷头条看到一篇文章写的滴滴出行2017秋招编程题,后来发现原文在这里http://www.cnblogs.com/SHERO-Vae/p/588 ...

随机推荐

  1. python爬虫——论抓包的正确姿势和学好Javascript的重要性(1)

    没事想爬下数据,就入了scrapy坑,跟着https://zhuanlan.zhihu.com/data-factory这篇教程走,中间被小数量的网站坑过,不过还是写出了爬虫~~ 切糕王子:毫无防御, ...

  2. Linux下Shell的for循环语句

    第一类:数字性循环-----------------------------for1-1.sh #!/bin/bash ;i<=;i++)); do + ); done ------------ ...

  3. python链接Hive

    之前一直用thrift链接Hive,但在运行时总出现问题,一直报缺少模块的错误,装了这个模块,又报缺少那个模块,连了半天,全是泪啊! 原来thrift链接Hive的.py文件后续没人维护,是连不上的. ...

  4. LeetCode--016--最接近的三数之和(java)

    给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一答案. 例如,给定数 ...

  5. Matlab:高阶常微分三种边界条件的特殊解法(隐式Euler)

    函数文件1: function b=F(f,x0,u,h) b(1,1)=x0(1)-h*x0(2)-u(1); b(2,1)=x0(2)+h*x0(1)^2-u(2)-h*f; 函数文件2: fun ...

  6. ceph crush的问题

    ceph crush的问题看一遍忘一遍,现将<ceph源码分析>一书中相关章节摘抄如下: 4.2.1 层级化的Cluster Map例4-1 Cluster Map定义层级化的Cluste ...

  7. VS2015在win10上编译的程序不能在Win7上运行的原因

    研究了下,搞懂原理了.是VS 2015 编译的问题,因为我是Win 10 ,所以会用到win 10 的SDK ,这个SDK 依赖了Universal C Runtime ,就是API-MS-CRT-X ...

  8. Php的基本语法学习

    1.php语法 当 PHP 解析一个文件时,会寻找开始和结束标记,标记告诉 PHP 开始和停止解释其中的代码. 1)标记语法 是以<?php 开头,?> 结束,相当于html标签的开始标签 ...

  9. MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.2 Static Map with Two Layers

    MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.2 Static Map with Two Layers 一.前言 上一篇博客< ...

  10. 聊一聊啥都不会的我自学Linux系统的历程

    Linux大家都不陌生,我是在大三的时候开始接触Linux,上课的时候一位给我们上课的老师闲聊的时候说,你们计算机专业的学生要好好去学Linux,对于你们以后发展或者是就业都很有帮助. 开始的时候是一 ...