美文网首页
js疑难杂症

js疑难杂症

作者: 前端小学生CBB | 来源:发表于2017-12-08 17:17 被阅读0次

JS的类型

1.基本类型有: String、Number、Boolean、Undefined、Null
2.复杂类型有:Function、RegExp、Array、Object、Date、Error
3.全局数据类型:Math

JS闭包

闭包简单的说就是一个函数能访问外部函数的变量,这就是闭包,比如说:

function a(x){
       var str=3;
      function b(y){
          console.log(x+y+str);
     }
}

要理解闭包,首先必须理解Javascript特殊的变量作用域。变量的作用域无非就是两种: 全局变量和局部变量;js中的特殊就在于它们两个内部的函数是可以访问外部全局变量的,但是外部是无法访问函数内的局部变量的比如:

//访问外部函数
var str = 123;
function test(){
  console.log(str)
}
test()//结果为 123
-----------
//访问内部函数
function test2(){
  var str2 = 234
}
test2();
console.log(str2)//报错‘str2 is not defined’

注意 :在访问内部函数的时候 如果申明变量没有使用 var 或者 let(ES6语法) 申明 ,js会认为这是一个全局变量,所以可以直接访问比如:

function test3(){
  str3 = 234
}
test3();
console.log(str3)//结果为 234

现实中的各种需求有时候也不讲道理的,可能你就真的需要去访问闭包里面的函数来达到你想要的效果,这时也难不住我们各路大神,比如:

function fn1(){
  var numb = 8899;
  function fn2(){
        console.log(numb)
    }
  return fn2
}
var fn3 = fn1();
fn3()

上面的函数运行时fn3()的结果就是 8899; 运用闭包的函数特点,可以访问父级函数的值, 当运行fn3的时候相当于运行了fn1,fn2可以直接获取fn1的局部变量,然后fn1直接返回fn2的值,这样当运行fn3的时候就得到了numb的值了

为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收;
参考:http://www.jb51.net/article/24101.htm
什么是闭包:
当内部函数 在定义它的作用域 的外部 被引用时,就创建了该内部函数的闭包 ,如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被 释放,因为闭包需要它们.

标志性的闭包函数题:

var  str = '全局变量';
var Fn = {
    str:'局部变量',
    getStr: function(){
      return function(){
        return this.str
      }
  }
}
console.log(Fn.getStr()())//结果为 ’全局变量‘

js函数继承

参考链接:https://www.zhihu.com/question/41466747/answer/132562725
1.原型继承
比如:

function a(name){
  this.name = name
}
a.prototype.consName = function(){
  console.log(this.name)
}
function b(age){
  this.age = age
}

 b.prototype = new a('hh')
var c = new b(12)
console.log(c.name)//结果'hh'
console.log(c.age)//结果为12
c.conName()//结果为hh

这样b通过原型继承了a,在new b的时候,c中有个隐藏的属性__proto__指向构造函数的prototype对象,在这里是a对象实例,a对象里面也有一个隐藏的属性__proto__,指向a构造函数的prototype对象,这个对象里面又有一个__proto__指向Objectprototype

这种方式有2个缺点,第一个缺点是所有子类共享父类实例,如果某一个子类修改了父类,其他的子类在继承的时候,会造成意想不到的后果。第二个缺点是在构造子类实例的时候,不能给父类传递参数。

2.构造函数继承

function a(name){
  this.name = name
}
function b(age,name){
  this.age = age;
  a.call(this,name)
}
var c = new b(12,'hha')
c.age//结果为12
c.name//结果为hha
注意,在确定需要将(call())a对象给b时, b()的参数必须要带上,否则会显示为空,或者你访问一个不存在的参数会显示未定义

采用这种方式继承是把a中的属性加到this上面,这样name相当于就是b的属性。这种方法的缺点是父类的prototype中的函数不能复用。

js执行顺序

js中国 函数(function)的优先级要高于var变量申明;
例如:

var name = 'hello';
(function(){
  if(typeof name === 'undefined'){
    console.log('123'+name)
}else{
  console.log('234'+name)  
}
})()
结果为:234hello
var name = 'hello';
(function(){
  if(typeof name === 'undefined'){
    var name = 'world';
    console.log('123'+name)
}else{
  console.log('234'+name)  
}
})()
结果为 :123world;

注意: 一般函数内部 使用变量会优先使用函数内部(相同于全局变量名称)的局部变量,
所以情况一 没有局部变量,自执行函数会直接使用 全局变量 ,而全局变量namehello;所以结果为234hello;
情况二 自执行函数执行的时候 name值未申明所以 是未定义,结果为123world

相关文章

  • js疑难杂症

    js 疑难杂症 ["1", "2", "3"].map(parseInt)? => [1,NAN, NAN] 原因...

  • js疑难杂症

    JS的类型 1.基本类型有: String、Number、Boolean、Undefined、Null2.复杂类型...

  • 佛莲儿💠疑难杂症

    佛莲儿疑难杂症

  • 日出

    投胎转世解决一切疑难杂症

  • 变现在学习的高效输出的那个阶段?

    “你以为你们跬步包治人生的所有疑难杂症啊!动不动就是来跬步!”她在那边调侃。 “治不治人生的各种疑难杂症,...

  • 什么是风湿?

    @桑红香18595530321 一个故事解决一个世界疑难杂症 一个故事解决了一个世界疑难杂症——风湿❗️ 什么是风...

  • 源哥钢构

    有关钢构的疑难杂症,欢迎大家留言讨论~

  • 茕茕孑立

    疑难杂症皆可医,唯有蠢字,无药可救。

  • 验方,偏方

    今天在学习的时候听到一个新名词叫验方。 以前只知道偏方,专治疑难杂症的偏方。因为这些疑难杂症自己也没有,所以知道的...

  • 验方,偏方

    今天在学习的时候听到一个新名词叫验方。 以前只知道偏方,专治疑难杂症的偏方。因为这些疑难杂症自己也没有,所以知道的...

网友评论

      本文标题:js疑难杂症

      本文链接:https://www.haomeiwen.com/subject/wacjixtx.html