草庐IT

js 高频面试题详解

莫凡 2023-03-28 原文

一:js 中的变量提升

例1

a = 2;
var a;
console.log(a);

答:2

解析:它会将当前作用域的所有变量的声明提升到程序的顶部,上述代码等价为:

var a;
 a = 2
console.log(a); // 2

例2:

console.log(a);// undefined 
var a = 2;

解析:变量的声明提升到程序的顶部;等价于:

var a;
console.log(a); 
a = 2;

问题:为什么会有变量提升?

其实啊,js和其他语言一样,都要经历编译和执行阶段,而在编译的时候,会搜集所有的变量并且在本作用域内提前声明,而且其他代码都不会改变顺序。

1:作用域:除了函数外,js是没有块级作用域

2:作用域链:内部可以访问外部的变量,但是外部不能访问内部的变量。 注意:如果内部有,优先查找到内部,如果内部没有就查找外部的。

3:js的变量声明:js的变量声明其实大体上可以分为三种:var声明、let与const声明和函数声明。

函数声明与其他声明一起出现的时候,是以谁为准呢?答案就是,函数声明高于一切,毕竟函数是js的第一公民。

所以下面函数的调用会输出谁呢? 答案是  foo

foo();
function foo() {
    console.log('foo');
}
var foo = 2;

那么下面又会输出谁呢?

foo();
 
function foo() {
    console.log('1');
}
 
function foo() {
    console.log('2');
}

答案是: 2  因为有多个函数声明的时候,是由最后面的函数声明来替代前面的。

那下列程序优惠输出什么呢?

foo();
 
var foo = function() {
    console.log('foo');
}

答案是报了Uncaught TypeError: foo is not a function 的异常

二:js 的作用域问题

1. 除了函数外,js是没有块级作用域。
2. 作用域链:内部可以访问外部的变量,但是外部不能访问内部的变量。
注意:如果内部有,优先查找到内部,如果内部没有就查找外部的。
3. 注意声明变量是用var还是没有写(window.)
4. 注意:js有变量提升的机制【变量悬挂声明】
5. 优先级:声明变量 > 声明普通函数 > 参数 > 变量提升

例1:

function c(){
var b=2
    function a(){
         console.log(b); // undefind
         var b=3
         console.log(b); // 3
   }
   a()
   console.log(b); // 2
 }
c()

 例2:

var name = 'a';
(function(){
    if( typeof name == 'undefined' ){
        var name = 'b';
        console.log('111'+name);
    }else{
        console.log('222'+name);
    }
})()

答案: 111b

 例3:

function fun( a ){
    var a = 10;
    function a(){}
    console.log( a );
}
 
fun( 100 );

答案: 10

三:js的对象考题

 例1:创建对象的三种方式

1:利用字面变量创建
var obj = {
       uname: '张三疯',
       age: 18,
       sex: '男',
       sayHi: function() {
             console.log('hi~');

         }
  }
2:new object 创建对象
var obj = new Object(); // 创建了一个空的对象
obj.uname = '张三疯';
 obj.age = 18;
 obj.sex = '男';
3: 构造函数创建对象

// new 构造函数名();
        function Star(uname, age, sex) {
            this.name = uname;
            this.age = age;
            this.sex = sex;
            this.sing = function(sang) {
                console.log(sang);

            }
        }
        var ldh = new Star('刘德华', 18, '男'); // 调用函数返回的是一个对象
        // console.log(typeof ldh);
        console.log(ldh.name);
        console.log(ldh['sex']);
        ldh.sing('冰雨');
        var zxy = new Star('张学友', 19, '男');
        console.log(zxy.name);
        console.log(zxy.age);
        zxy.sing('李香兰')
注意:

   // 1. 构造函数名字首字母要大写
        // 2. 我们构造函数不需要return 就可以返回结果
        // 3. 我们调用构造函数 必须使用 new
        // 4. 我们只要new Star() 调用函数就创建一个对象 ldh  {}
        // 5. 我们的属性和方法前面必须添加 this
View Code

 例2:浅谈构造函数和对象

// 构造函数和对象
        // 1. 构造函数  明星 泛指的某一大类  它类似于 java 语言里面的  类(class)
        function Star(uname, age, sex) {
            this.name = uname;
            this.age = age;
            this.sex = sex;
            this.sing = function(sang) {
                console.log(sang);

            }
        }
        // 2. 对象 特指 是一个具体的事物 刘德华 ==  {name: "刘德华", age: 18, sex: "男", sing: ƒ}
        var ldh = new Star('刘德华', 18, '男'); // 调用函数返回的是一个对象
        console.log(ldh);
        // 3. 我们利用构造函数创建对象的过程我们也称为对象的实例化
View Code

 例3:new关键字的执行过程

// new关键字执行过程
        // 1. new 构造函数可以在内存中创建了一个空的对象 
        // 2. this 就会指向刚才创建的空对象
        // 3. 执行构造函数里面的代码 给这个空对象添加属性和方法
        // 4. 返回这个对象
        function Star(uname, age, sex) {
            this.name = uname;
            this.age = age;
            this.sex = sex;
            this.sing = function(sang) {
                console.log(sang);

            }
        }
        var ldh = new Star('刘德华', 18, '男');
View Code

js对象的注意点:

1. 对象是通过new操作符构建出来的,所以对象之间不想等(除了引用外);
2. 对象注意:引用类型(共同一个地址);
3. 对象的key都是字符串类型;
4. 对象如何找属性|方法;
    查找规则:先在对象本身找 ===> 构造函数中找 ===> 对象原型中找 ===> 构造函数原型中找 ===> 对象上一层原型查找

 例3:[1,2,3] ==[1,2,3]  // false      [1,2,3] ===[1,2,3]  // false

 例4:

var obj1 = {
    a:'hellow'
}
var obj2 = obj1;
obj2.a = 'world';
console.log(obj1);     //{a:world}
(function(){
    console.log(a);     //undefined
    var a = 1;
})();

注意: js中的数据类型包含 基本数据类型和引用数据类型。

 

例5:

var a = {}
var b = {
    key:'a'
}
var c = {
    key:'c'
}
 
a[b] = '123';
a[c] = '456';
 
console.log( a ); // {"[object Object]": "456"}
console.log( a[b] ); // 456

 四:JS作用域+this指向+原型的考题

 1:原型:每一个构造函数都有一个 prototype 属性,指向另一个对象。这个 prototype 就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。

2:对象原型_proto_:对象身上系统自己添加一个 __proto__ 指向我们构造函数的原型对象 prototype

3:实例对象原型( __proto__)和构造函数原型对象(prototype)里面都有一个属性 constructor 属性 ,constructor 我们称为构造函数,因为它指回构造函数本身

4: 原型链:每一个实例对象又有一个__proto__属性,指向的构造函数的原型对象,构造函数的原型对象也是一个对象,也有__proto__属性,这样一层一层往上找就形成了原型链。

5:对象成员的查找规则:当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。如果还没有就查找原型对象的原型(Object的原型对象)。依此类推一直找到 Object 为止(null),按照原型链的方式去查找。

6:原型对象的this指向:

例1:

function Foo(){
    getName = function(){console.log(1)} //注意是全局的window.
    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();//3

例2:

var o = {
    a:10,
    b:{
        a:2,
        fn:function(){
            console.log( this.a ); // 2
            console.log( this );   //代表b对象
        }
    }
}
o.b.fn();

 

例3:

window.name = 'ByteDance';
function A(){
    this.name = 123;
}
A.prototype.getA = function(){
    console.log( this );
    return this.name + 1;
}
let a = new A();
let funcA = a.getA;
funcA();  //this代表window

例4:

var length = 10;
function fn(){
    return this.length + 1;
}
var obj = {
    length:5,
    test1:function(){
        return fn();
    }
}
obj.test2 = fn;
console.log( obj.test1() );                             //1
console.log( fn()===obj.test2() );                 //false
console.log( obj.test1() == obj.test2() ); //false

1. 原型可以解决什么问题

对象共享属性和共享方法
2. 谁有原型

函数拥有:prototype
对象拥有:__proto__
3. 对象查找属性或者方法的顺序

先在对象本身查找 --> 构造函数中查找 --> 对象的原型 --> 构造函数的原型中 --> 当前原型的原型中查找
4. 原型链
4.1 是什么?:就是把原型串联起来
4.2 原型链的最顶端是null

详解试题spancolorstyleJavaScript

有关js 高频面试题详解的更多相关文章

  1. Hive SQL 五大经典面试题 - 2

    目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类

  2. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  3. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

    rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

  4. node.js - 如何在 Travis CI 上的一个项目中运行 Node.js 和 Ruby 测试 - 2

    我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每

  5. 物联网MQTT协议详解 - 2

    一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su

  6. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

  7. node.js - 从未编写过任何自动化测试,我应该如何开始行为驱动开发? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。多年来,我一直在使用多种语言进行编程,并且认为自己总体上相当擅长。但是,我从未编写过任何自动化测试:没有单元测试,没有TDD,没有BDD,什么都没有。我已经尝试开始为我的项目编写适当的测试套件。我可以看到在进行任何更改后能够自动测试项目中所有代码的理论值(value)。我可以看到像RSpec和Mocha这样的测试框架应该如何使设置和运行所述测试变得相当容易

  8. ruby-on-rails - 将 Angular JS 与 Rails 集成 - 2

    我需要一些指导来了解如何将Angular整合到rails中。选择Rails的原因:我喜欢他们偏执的做事方式。还有迁移,gem真的很酷。使用angular的原因:我正在研究和寻找最适合SPA的框架。Backbone似乎太抽象了。我不得不在Angular和Ember之间做出选择。我首先开始阅读Angular,它对我来说很有意义。所以我从来没有去读过关于ember的文章。使用Angular和Rails的原因:我研究并尝试使用小型框架,例如grape、slim(是的,我也使用php)。但我觉得需要坚持项目的长期范围。我个人喜欢用Rails的方式做事。这就是我需要帮助的地方,我在Rails4中有

  9. node.js - 如何比较图像并确定哪个内容更多? - 2

    目标:我想从动画GIF中抓取最佳帧并将其用作静态预览图像。我相信最好的帧是显示最多内容的帧-不一定是第一帧或最后一帧。以这张动图为例:--这是第一帧:--这是第28帧:很明显,第28帧很好地代表了整个GIF。我如何以编程方式确定一帧是否比另一帧具有更多像素/内容?如果您能向我指出任何想法、想法、包/模块或文章,我们将不胜感激。 最佳答案 实现此目的的一种直接方法是估计entropy每个图像的帧,并选择具有最大熵的帧。在信息论中,熵可以被认为是图像的“随机性”。单一颜色的图像是非常可预测的,分布越平坦,越随机。这与Arthur-R描述

  10. 【详解】Docker安装Elasticsearch7.16.1集群 - 2

    开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建

随机推荐