资讯专栏INFORMATION COLUMN

变量类型、原型、闭包、作用域面试题及知识点简单总结

mj / 3261人阅读

摘要:值类型是将变量的值存在内存中。说明几种不同的使用场景作为构造函数对象属性普通函数执行,创建个标签,点击时弹出对应序号如何理解作用域自由变量作用域链,即自由变量的寻找闭包的两个场景。

变量类型和计算知识点: 值类型、引用类型
//值类型
var a=100
var b=a
a=200
console.log(b) //100
//引用类型
var a={age:20}
var b=a
b.age=21
console.log(a.age) //21
typeof
// Numbers
typeof 37 === "number";
typeof 3.14 === "number";
typeof Math.LN2 === "number";
typeof Infinity === "number";
typeof NaN === "number"; // 尽管NaN是"Not-A-Number"的缩写
typeof Number(1) === "number"; // 但不要使用这种形式!
// Strings
typeof "" === "string";
typeof "bla" === "string";
typeof (typeof 1) === "string"; // typeof总是返回一个字符串
typeof String("abc") === "string"; // 但不要使用这种形式!
// Booleans
typeof true === "boolean";
typeof false === "boolean";
typeof Boolean(true) === "boolean"; // 但不要使用这种形式!
// Symbols
typeof Symbol() === "symbol";
typeof Symbol("foo") === "symbol";
typeof Symbol.iterator === "symbol";
// Undefined
typeof undefined === "undefined";
typeof declaredButUndefinedVariable === "undefined";
typeof undeclaredVariable === "undefined"; 
// Objects
typeof {a:1} === "object";
// 使用Array.isArray 或者 Object.prototype.toString.call
// 区分数组,普通对象
typeof [1, 2, 4] === "object";
typeof new Date() === "object";
// 下面的容易令人迷惑,不要使用!
typeof new Boolean(true) === "object";
typeof new Number(1) ==== "object";
typeof new String("abc") === "object";
// 函数
typeof function(){} === "function";
typeof Math.sin === "function";
//NaN
typeof 1/0 === "NaN";
//null
typeof null === "object";
强制类型转换
//逻辑运算符
console.log(10 & 0) //0  转换为true&&0
console.log(""||"abc") //abc  转换为false||"abc"
console.log(!window.abc) //true  !undefined为true
//if语句 false情况
null "" false 0 NaN undefined
//判断一个变量是否当作true或者false
var a = 100
console.log(!!a)
面试题:

1.JS中使用typeof能得到哪些类型
undefined null string number object function boolean symbol
2.何时使用"===",何时使用"=="
参考jQuery源码 只有这种情况下使用"==":

if(obj.a == null) {
}
//这句相当于obj.a === null || obj.a === undefined

3.JS有哪些内置函数
Object Array String Number Function Boolean Date RegExp Error
4.JS变量按照存储方式分为哪些类型,并描述其特点
值类型、引用类型。
值类型是将变量的值存在内存中。
引用类型的变量是真实变量的指针(对象、数组、函数)。可以无限扩张属性。
5.如何理解JSON
是JavaScript的对象,内置两个方法 JSON.stringify JSON.parse

原型知识点: 构造函数
function Foo(name, age) {
  this.name = name
  this.age = age 
  this.class = "class-1"
  //return this  默认有这行
}

var f = new Foo("zs", 20)

//执行过程:1.new函数执行时this会变成空对象 2.this. 的时候赋值 3.return this 4.给f赋值


//var a = {}         ===> var a = new Object()
//var a =[]          ===> var a = new Array()
//function Foo(){}   ===> var Foo = new Function()
//instanceof 用于判断一个函数是否是一个变量的构造函数
原型规则
//所有的引用类型(数组、对象、函数)都具有对象特性,除了null之外,都可以自由扩展属性
//所有的引用类型 都有__proto__ 隐式原型
//所有的函数都有 prototype 显式原型   属性值也是一个普通对象
//所有的引用类型(数组、对象、函数),__proto__属性值指向它的构造函数的prototype属性值
var obj = {}; obj.a = 100
var arr = []; arr.a = 100
function fn () {}
fn.a = 100

console.log(obj.__proto__)
console.log(arr.__proto__)
console.log(fn.__proto__)

console.log(fn.prototype)

console.log(obj.__proto__ === Object.prototype)


//试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(构造函数的prototype)中寻找
function Foo(name, age) {
  this.name = name
}

Foo.prototype.alertName = function () {
  alert(this.name)
}

var f = new Foo("zs")
f.printName = function () {
  console.log(this.name)
}

f.printName()
f.alertName()
原型链 instanceof
//instanceof 是用于判断引用类型属于哪个构造函数的方法
//构造函数
function Foo(name, age) {
  this.name = name
}

Foo.prototype.alertName = function () {
  alert(this.name)
}

//创建实例
var f = new Foo("zs")
f.printName = function () {
  console.log(this.name)
}


f.printName()
f.alertName()
f.toString()


// f instanceof Foo 判断过程:
// f 的 __proto__一层层往上找到是否对应Foo.prototype
// 再判断f instanceof Object

直角矩形是构造函数 圆角矩形是对象

hasOwnProperty
var obj={
x:100,
y:200,
z:300
}
var key
for(key in obj){
//hasOwnProperty会返回一个布尔值,判断是否是原生的属性,以此来排除原型链上的属性
if(obj.hasOwnProperty(key)){
  console.log(key,obj[key]);
}
}
//x 100
//y 200
//z 300
面试题

6.如何准确判断一个变量是数组函数

var arr = []
arr instanceof Array
typeof arr //object, typeof 是无法判断是否是数组的

7.写一个原型链继承的例子

function Elem(id) {
  this.elem = document.getElementById(id)
}

Elem.prototype.html = function (val) {
  var elem = this.elem
  if (val) {
    elem.innerHTML = val
    return this
  } else {
    return elem.innerHTML
  }
}

Elem.prototype.on = function (type, fn) {
  var elem = this.elem
  elem.addEventListener(type, fn)
  return this
}

var div1 = new Elem("wrapper")
div1.html("

hello

").on("click", function () { alert("clicked") }).html("

javascript

")

8.描述new一个对象的过程

//创建一个对象
//this指向这个对象
//执行代码  即对this赋值
//返回this
function Foo(name, age) {
  this.name = name 
  this.age = age
  this.class = "class-1"
  //return this   构造函数最好不要写return
}

var f = new Foo("zs", 20)
作用域和闭包知识点: 执行上下文
//执行上下文:当前被执行代码的环境/作用域
console.log(a)
var a = 100

fn("zs")
//函数声明
function fn(name) {

  console.log(this)
  console.log(arguments)

  age = 20
  console.log(name, age)
  var age

  bar(100)

  function bar(num) {
    console.log(num)
  }
}
//函数表达式: var fn = function () {}


//在全局代码执行前,会将变量定义和函数声明先提出来
//在函数代码执行前,会将变量定义,函数声明,this,arguments(所有参数的集合)先提出来
this
//this的值执行时才能确定
var a = {
  name: "A",
  fn: function () {
    console.log(this.name)  //这个阶段的this无法确定值
  }
}


a.fn()                  //this === a
a.fn.call({name: "B"})  //this === {name: "B"}
var fn1 = a.fn
fn1()                   //this === window

//作为构造函数执行
function Foo(name) {
  // this = {}
  this.name = name
  // return this
}
var f = new Foo("zs")
//作为对象属性执行
var obj = {
  name: "A",
  printName: function () {
    console.log(this.name)    //这里this就是obj
  }
}
obj.printName
//作为普通函数执行
function fn() {
  console.log(this)       //这里的this就是window
}
fn
//call apply bind
function fn1(name, age) {
  console.log(name)
  console.log(this)       //这里的this是{x:100}
}
fn1.call({x:100}, "zs", 20)


var fn2h = function fn2(name, age) {
  console.log(name)
  console.log(this)       //这里的this是{y:200}
}.bind({y:200})
fn2("zs", 20)
作用域 作用域链
//不断向父级作用域寻找变量的过程形成了作用域链
//没有块级作用域概念
if (true) {
  var name = "zs"
}
console.log(name)


//函数、全局作用域
var a = 10
function fn() {
  var a = 200
  console.log("fn", a)
}
console.log("global", a)
fn()


var b = 100
function fn() {
  var c = 200

  console.log(b)  //当前作用域没有定义的变量叫做自由变量
  console.log(c)  
}
fn()

var a = 100
function f1() {
  var b = 200
  function f2() {
    var c = 300

    console.log(a)
    console.log(b)
    console.log(c)
  }
  f2()
}
f1()
//哪个作用域定义了f1这个函数,f1的父级作用域就是谁
闭包
//闭包应用:1.函数作为返回值
function F1() {
  var a = 100

  //返回一个函数  
  return function () {
    console.log(a)     //100
  }
}

//f1得到一个函数
var f1 = F1()
var a = 200
f1()


//2.函数作为参数传递
function F1() {
  var a = 100
  return function() {
    console.log(a)  //100
  }
}

var f1 = F1()

function F2(fn) {
  var a = 200
  fn()
}
F2(f1)
面试题

9.说一下对变量提升的理解
变量定义、函数声明会提前。
10.说明this几种不同的使用场景
作为构造函数、对象属性、普通函数执行,call apply bind
11.创建10个标签,点击时弹出对应序号

var i
  for (i = 0; i < 10; i++) {
    (function (i) {
      var a = document.createElement("a")
      a.innerHTML = i + "
" a.addEventListener("click", function (e) { e.preventDefault() alert(i) }) document.body.appendChild(a) })(i) }

12.如何理解作用域
自由变量、作用域链,即自由变量的寻找、闭包的两个场景。
13.实际开发中闭包的应用
封装变量,收敛权限 案例:

function isFirstLoad() {
  var _list = []
  return function (id) {
    if (_list.indexOf(id) >=0) {
      return false
    } else {
      _list.push(id)
      return true
    }
  }
}

var firstLoad = isFirstLoad()
console.log(firstLoad(10))
console.log(firstLoad(10))
console.log(firstLoad(20))
console.log(firstLoad(20))

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

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

相关文章

  • 56 道高频 JavaScript 与 ES6+ 的面试题及答案

    摘要:线程的划分尺度小于进程,使得多线程程序的并发性高。线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口顺序执行序列和程序的出口。从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。 showImg(https://segmentfault.com/img/bVbv2GE?w=900&h=400); 前言 本文讲解 56 道 JavaScript...

    zengdongbao 评论0 收藏0
  • 面试识点总结

    摘要:最近面试几家前端职位,想知道目前的前端面试题是偏向哪一块,都主要问到的是语法,闭包,原型链,继承那一块。并且将面试题的知识点汇总一下。参考网站面试题图片过多的时候如何优化图标很多的时候可以用雪碧图图片过大时候可以压缩一下。 最近面试几家前端职位,想知道目前的前端面试题是偏向哪一块,都主要问到的是ES6语法,闭包,原型链,继承那一块。并且将面试题的知识点汇总一下。有助于下次面试。 1.H...

    王晗 评论0 收藏0
  • 面试识点总结

    摘要:最近面试几家前端职位,想知道目前的前端面试题是偏向哪一块,都主要问到的是语法,闭包,原型链,继承那一块。并且将面试题的知识点汇总一下。参考网站面试题图片过多的时候如何优化图标很多的时候可以用雪碧图图片过大时候可以压缩一下。 最近面试几家前端职位,想知道目前的前端面试题是偏向哪一块,都主要问到的是ES6语法,闭包,原型链,继承那一块。并且将面试题的知识点汇总一下。有助于下次面试。 1.H...

    CrazyCodes 评论0 收藏0
  • JavaScript - 收藏集 - 掘金

    摘要:插件开发前端掘金作者原文地址译者插件是为应用添加全局功能的一种强大而且简单的方式。提供了与使用掌控异步前端掘金教你使用在行代码内优雅的实现文件分片断点续传。 Vue.js 插件开发 - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins译者:jeneser Vue.js插件是为应用添加全局功能的一种强大而且简单的方式。插....

    izhuhaodev 评论0 收藏0

发表评论

0条评论

mj

|高级讲师

TA的文章

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