资讯专栏INFORMATION COLUMN

JavaScript Interview Algorithm Questions

dongxiawu / 962人阅读

摘要:原文链接猛戳这里构造函数下面生成实例这时和会自动含有一个属性,指向它们的构造函数。这个对象的所有属性和方法,都会被构造函数的实例继承。

JavaScript的严格模式和正常模式

"use strict";
顾名思义也就是 JavaScript 会在所谓严格模式下执行,其一个主要的优势在于能够强制开发者避免使用未声明的变量。对于老版本的浏览器或者执行引擎则会自动忽略该指令。

在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,全局变量必须显式声明。

"use strict";
  v = 1; // 报错,v未声明
  for(i = 0; i < 2; i++) { // 报错,i未声明
  }

因此,严格模式下,变量都必须先用var命令声明,然后再使用。

Javascript语言的一个特点,就是允许"动态绑定",即某些属性和方法到底属于哪一个对象,不是在编译时确定的,而是在运行时(runtime)确定的。
严格模式对动态绑定做了一些限制。某些情况下,只允许静态绑定。也就是说,属性和方法到底归属哪个对象,在编译阶段就确定。这样做有利于编译效率的提高,也使得代码更容易阅读,更少出现意外。

因为下面的代码不是在严格模式下执行,并且this的值不会在函数执行时被设置,此时的this的值会默认设置为全局对象。

function f2(){
  "use strict"; // 这里是严格模式
  return this;
}

f2() === undefined; // true

更全面的信息参考这个链接

JavaScript作用域和变量提升

考虑下面程序的运行结果

var foo = 1;  
function bar() {  
    if (!foo) {  
        var foo = 10;  
    }  
    alert(foo);  
}  
bar();  

结果是10;
再看下面这个

var a = 1;  
function b() {  
    a = 10;  
    return;  
    function a() {}  
}  
b();  
alert(a); 

结果是1

出乎意料的结果是由于“Hoisting (变量提升)”的原因,要理解其中的原理需要先了解下JavaScript的作用域scope。

javascript作用域(函数作用域)与C语言作用域(块级作用域)不同

int main() {  
    int x = 1;  
    printf("%d, ", x); // 1  
    if (1) {  
        int x = 2;  
        printf("%d, ", x); // 2  
    }  
    printf("%d
", x); // 1  
}  

这是因为C家族的语言有块作用域,当程序控制走进一个块,比如if块,只作用于该块的变量可以被声明,而不会影响块外面的作用域。但是在Javascript里面,这样不行

var x = 1;  
console.log(x); // 1  
if (true) {  
    var x = 2;  
    console.log(x); // 2  
}  
console.log(x); // 2  

函数声明和变量声明总是会被解释器悄悄地被“提升”到方法体的最顶部。这个意思是,像下面的代码:

function foo() {  
    bar();  
    var x = 1;  
} 

实际上会被解释成:

function foo() {  
    var x;  
    bar();  
    x = 1;  
}  

无论定义该变量的块是否能被执行。下面的两个函数实际上是一回事:

function foo() {  
    if (false) {  
        var x = 1;  
    }  
    return;  
    var y = 1;  
}  
function foo() {  
    var x, y;  
    if (false) {  
        x = 1;  
    }  
    return;  
    y = 1;  
}  

只有函数式的声明才会连同函数体一起被提升。foo的声明会被提升,但是它指向的函数体只会在执行的时候才被赋值

function test() {  
    foo(); // TypeError "foo is not a function"  
    bar(); // "this will run!"  
    var foo = function () { // 变量指向函数表达式  
        alert("this won"t run!");  
    }  
    function bar() { // 函数声明 函数名为bar  
        alert("this will run!");  
    }  
}  
test(); 

如果程序员不能很好的理解变量提升,他们写的程序就容易出现一些问题。
为了避免这些问题,通常我们在每个作用域开始前声明这些变量,这也是正常的 JavaScript 解析步骤,易于我们理解。

JavaScript 严格模式(strict mode)不允许使用未声明的变量。

原文链接猛戳这里

JavaScript Object-Oriented JavaScript构造函数
function Person (name,age) {
    this.name = name;
    this.age = age;
    this.type = "human";
    this.play = function(){console.log("video game")};
}

//下面生成实例
var Person1 = new Person("Tom",25);
var Person2 = new Person("Jack",26);
alert(Person1.name);

//这时Person1和Person2会自动含有一个constructor属性,指向它们的构造函数。
alert(Person1.constructor);
//Javascript还提供了一个instanceof运算符,验证原型对象与实例对象之间的关系
alert(Person1 instanceof Person); //true

alert(Person1.type == Person2.type);//ture
alert(Person1.play == Person2.play);//false

type属性和play()方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存.

Prototype模式

Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。
这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上.

function Person (name,age) {
    this.name = name;
    this.age = age;
}
Person.prototype.type = "human";
Person.prototype.play = function(){console.log("video game")};

var Person1 = new Person("Tom",25);
var Person2 = new Person("Jack",26);
alert(Person1.type); //human
alert(Person1.play == Person2.play); //true

这时所有实例的type属性和play()方法,其实都是同一个内存地址,指向prototype对象,使用原型的好处是可以让对象实例共享它所包含的属性和方法,因此就提高了运行效率。

在JavaScript中,一共有两种类型的值,原始值和对象值。每个对象都有一个内部属性 prototype ,我们通常称之为原型。原型的值可以是一个对象,也可以是null。如果它的值是一个对象,则这个对象也一定有自己的原型。这样就形成了一条线性的链,我们称之为原型链。
关于原型、原型链-猛戳

ECMAScript数据类型 原始类型

ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。
原始数据类型

引用类型

引用类型通常叫做类(class),也就是说,遇到引用值,所处理的就是对象。

Object 对象
Object 对象自身用处不大,不过在了解其他类之前,还是应该了解它。因为 ECMAScript 中的 Object 对象与 Java 中的 java.lang.Object 相似,ECMAScript 中的所有对象都由这个对象继承而来,Object 对象中的所有属性和方法都会出现在其他对象中,所以理解了 Object 对象,就可以更好地理解其他对象。

Object 对象具有下列属性
constructor
对创建对象的函数的引用(指针)。对于 Object 对象,该指针指向原始的 Object() 函数。
Prototype
对该对象的对象原型的引用。对于所有的对象,它默认返回 Object 对象的一个实例。

类型转换

所有程序设计语言最重要的特征之一是具有进行类型转换的能力。
ECMAScript 给开发者提供了大量简单的类型转换方法。

toString()

parseInt()

parseFloat()

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

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

相关文章

  • 【转自百度fex】fex-team/interview-questions

    摘要:注意目前发现有其他人以团队名义进行招聘,发出的邮箱皆为私人邮箱。为防止在投递简历出现误会,在此提醒各位注意团队没有以任何个人名义或邮箱进行招聘。的面试过程我们一般会有轮面试,对于高级别的工程师可能会有轮面试。 fex-team/interview-questions 注意 目前发现有其他人以 FEX 团队名义进行招聘,发出的邮箱皆为私人邮箱。 为防止在投递简历出现误会,在此提醒各位注意...

    468122151 评论0 收藏0
  • 【转自百度fex】fex-team/interview-questions

    摘要:注意目前发现有其他人以团队名义进行招聘,发出的邮箱皆为私人邮箱。为防止在投递简历出现误会,在此提醒各位注意团队没有以任何个人名义或邮箱进行招聘。的面试过程我们一般会有轮面试,对于高级别的工程师可能会有轮面试。 fex-team/interview-questions 注意 目前发现有其他人以 FEX 团队名义进行招聘,发出的邮箱皆为私人邮箱。 为防止在投递简历出现误会,在此提醒各位注意...

    fou7 评论0 收藏0
  • 【转自百度fex】fex-team/interview-questions

    摘要:注意目前发现有其他人以团队名义进行招聘,发出的邮箱皆为私人邮箱。为防止在投递简历出现误会,在此提醒各位注意团队没有以任何个人名义或邮箱进行招聘。的面试过程我们一般会有轮面试,对于高级别的工程师可能会有轮面试。 fex-team/interview-questions 注意 目前发现有其他人以 FEX 团队名义进行招聘,发出的邮箱皆为私人邮箱。 为防止在投递简历出现误会,在此提醒各位注意...

    aisuhua 评论0 收藏0
  • 面试集 - 收藏集 - 掘金

    摘要:计算数组的极值微信面试题获取元素的最终前端掘金一题目用代码求出页面上一个元素的最终的,不考虑浏览器,不考虑元素情况。 Excuse me?这个前端面试在搞事! - 前端 - 掘金金三银四搞事季,前端这个近年的热门领域,搞事气氛特别强烈,我朋友小伟最近就在疯狂面试,遇到了许多有趣的面试官,有趣的面试题,我来帮这个搞事 boy 转述一下。 以下是我一个朋友的故事,真的不是我。 ... ja...

    crossea 评论0 收藏0
  • CSS技巧 - 收藏集 - 掘金

    摘要:笔者作为一位,将工作以来用到的各种优秀资料神器及框架整理在此,毕竟好记性不如烂键盘,此前端知识点大百科全书前端掘金,,不定期更新技巧前端掘金技巧,偶尔更新。计算数组的极值技巧使你的更加专业前端掘金一个帮你提升技巧的收藏集。 CSS 样式画各种图形 - 前端 - 掘金下面是一些我在 CSS 中经常用到的图案,还有一些是在css-tricks看到的。记录一下,以后会用到。会持续更新… 一、...

    Jonathan Shieber 评论0 收藏0

发表评论

0条评论

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