资讯专栏INFORMATION COLUMN

你真的知道JS吗?

Half / 3034人阅读

摘要:你真的知道吗是一门奇怪的语言,要真正掌握并不容易。废话不多说,来一个快速测试,道题目,看看你对是否真正掌握。操作符用来判断某个属性属于某个对象,可以是对象的直接属性,也可以是通过继承的属性。很多人会认为打印的是。

你真的知道JavaScript吗

    JavaScript是一门奇怪的语言,要真正掌握并不容易。废话不多说,来一个快速测试,5道题目,看看你对JavaScript是否真正掌握。准备好了吗?开始咯?

题目 No.1
if (!("a" in window)) {
    var a = 1;
}

console.log(a);
No.2
var a = 1,
    b = function a(x) {
        x && a(--x);
    };
console.log(a);
No.3
function a(x) {
    return x * 2;
}
var a;
console.log(a);
No.4
function b(x, y, a) {
    arguments[2] = 10;
    console.log(a);
}
b(1, 2, 3);
No.5
function a() {
    console.log(this);
}
a.call(null);
解析 No.1

    在浏览器环境中,全局变量都是window的一个属性,即
var a = 1 等价于 window.a = 1in操作符用来判断某个属性属于某个对象,可以是对象的直接属性,也可以是通过prototype继承的属性。
    再看题目,在浏览器中,如果没有全局变量 a ,则声明一个全局变量 a (ES5没有块级作用域),并且赋值为1。很多人会认为打印的是1。非也,大家不要忘了变量声明会被前置!什么意思呢?题目也就等价于

var a;

if (!("a" in window)) {
    a = 1;
}

console.log(a);

所以其实已经声明了变量a,只不过if语句之前值是undefined,所以if语句压根不会执行。
最后答案就是 undefined

No.2

这道题有几个需要注意的地方:

变量声明、函数声明会被前置,但是函数表达式并不会,准确说类似变量声明前置,举个栗子:

console.log("b", b); // b undefined
var b = function() {}
console.log("b", b); // b function () {}

2.具名的函数表达式的名字只能在该函数内部取到,举个例子(排除老的IE?):

var foo = function bar () {}

console.log("foo", foo); 
// foo function bar(){}

console.log("bar", bar);
// Uncaught ReferenceError: bar is not defined

    综合这两点,再看题目,最后输出的内容就为 1

No.3

函数声明会覆盖变量声明,但不会覆盖变量赋值,举个栗子简单粗暴:

function foo(){
    return 1;
}
var foo;
console.log(typeof foo);    // "function"

函数声明的优先级高于变量声明的优先级,但如果该变量foo赋值了,那结果就完全不一样了:

function foo(){
    return 1;
}
var foo = 1;
console.log(typeof foo);    // "number"

变量foo赋值以后,变量赋值初始化就覆盖了函数声明。这个需要注意
再看题目

function a(x) {
    return x * 2;
}
var a;
console.log(a); // function a(x) {...}
No.4

这题考察 arguments 对象的用法(详看?JavaScript中的arguments对象)
一般情况arguments与函数参数是动态绑定关系(为什么说是一般稍后会解释),所以很好理解,最后输出的是10

但是但是但是,我们不要忘了一个特殊情况--严格模式,在严格模式中 arguments 与相当于函数参数的一个拷贝,并没有动态绑定关系,举个栗子:

"use strict"
// 严格模式!!

function b(x, y, a) {
    arguments[2] = 10;
    console.log(a);
}
b(1, 2, 3); // 3
No.5
function a() {
    console.log(this);
}
a.call(null);

关于 a.call(null); 根据ECMAScript262规范规定:
如果第一个参数传入的对象调用者是null或者undefined的话,call方法将把全局对象(浏览器上是window对象)作为this的值。所以,不管你什么时候传入null或者 undefined,其this都是全局对象window。所以,在浏览器上答案是输出 window 对象。

但是但是但是,我们依旧不能忘记一个特殊情况--严格模式,在严格模式中,null 就是 nullundefined 就是 undefined ,举个栗子:

"use strict";
// 严格模式!!

function a() {
    console.log(this);
}
a.call(null); // null
a.call(undefined); // undefined
提醒

在浏览器中的全局对象是window,Node.js中是global;

为了使代码更加严谨与健壮,建议写JS都加上严格模式"use strict";

ES6已经成为前端必备技能,呼吁大家都使用ES6,方便高效,可以使用babel把ES6转成ES5甚至ES3,尽量使用ES6推动前端的发展?

About

GitHub: ?https://github.com/microzz
个人网站: ?https://microzz.com/

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82786.html

相关文章

  • 2019前端工程师自检清单与思考

    摘要:前端工程师自检清单对于,掌握其语法和特性是最基本的,但是这些只是应用能力,最终仍旧考量仍然是计算机体系的理论知识,所以数据结构,算法,软件工程,设计模式等基础知识对前端工程师同样重要,这些知识的理解程度,可以决定你在前端工程师这条路上能走多 2019前端工程师自检清单 对于JavaScript,掌握其语法和特性是最基本的,但是这些只是应用能力,最终仍旧考量仍然是计算机体系的理论知识,所...

    Honwhy 评论0 收藏0
  • JS基础篇--JS的DOM操作 - 真的了解?

    摘要:摘要想稍微系统的说说对于的操作把和常用操作的内容归纳成思维导图方便阅读同时加入性能上的一些问题前言在前端开发的过程中极为重要的一个功能就是对对象的操作无论增删改查在前端页面操作这一范围内都是比较消耗性能的如何高效率的便捷的操作这就是本文要讲 摘要 想稍微系统的说说对于DOM的操作,把Javascript和jQuery常用操作DOM的内容归纳成思维导图方便阅读,同时加入性能上的一些问题....

    DirtyMind 评论0 收藏0
  • 大话-node真的是单线程

    摘要:当你使用的活动监视器你会发现,实际的进程数为菜鸟是因为线程池的原因吗老鸟不错嘛,还知道线程池呢但非也非也。菜鸟竟然不是线程池老鸟你忽视了集成了引擎。启动后会创建实例,而实例是多线程的。 老鸟:伸着懒腰,看着窗外明媚的阳光,喝一口清茶,心情大美。一天的好心情莫过于此。老鸟:菜鸟,你这消失了大半个月,忙什么呢?菜鸟:听说node最近很火,这不趁着年轻,多储存点知识储备呢!老鸟:那你说说你对...

    Yang_River 评论0 收藏0
  • ES6时代,真的会克隆对象(二)

    摘要:多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。比如,表达式会返回,因为属性得到的仅仅是构造函数,而且是可以被手动更改的,只是返回的构造函数的名字,它并不返回类名。 原文:ES6时代,你真的会克隆对象吗(二) 上一篇,我们从Symbol和是否可枚举以及属性描述符的角度分析了ES6下怎么浅拷贝一个对象,发表在掘金和segmentfault上(...

    BoYang 评论0 收藏0
  • ES6时代,真的会克隆对象

    摘要:原文你真的会克隆对象吗开始之前在开始聊克隆之前,我们还是先来看看数据类型。值通过函数生成,是独一无二的。同时,中规定了对象的属性名有两种类型,一种是字符串,另一种就是类型。返回一个数组,包含对象自身的所有属性的键名。 原文:你真的会克隆对象吗 开始之前 在开始聊克隆之前,我们还是先来看看js数据类型。js的数据类型分为基本数据类型和复杂数据类型。 基本数据类型:Number、Bool...

    xiaokai 评论0 收藏0

发表评论

0条评论

Half

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<