javascript

1.对象

      1.1 分类

  1. 基本(值)数据类型 -----赋值的时候是直接在栈中将值赋予了
    • Number
    • String
    • Boolean
    • undefined
    • null
  2. 对象(引用)类型 ------------从堆中创建对象,然后将地址给予栈中的变量.
    • Object 任意对象
    • Function 函数一种特别的对象可以执行
    • Array 数值

      1.2 判断

  1. typeof 返回的是字符串
    • 基本数据类型 (null 为 Object) / Function为function /其余的对象类型会判断成Object
  2. instanceof 判断对象(引用)类型
    • Object 、Array、Function
  3. ===
    • 可以判断undefined 、null
  // typeof: 返回的是数据类型的字符串表达形式
  //1. 基本类型
  var a
  console.log(a, typeof a, a===undefined) // undefined 'undefined' true
  console.log(a===typeof a) // false

  a = 3
  console.log(typeof a === 'number')
  a = 'atguigu'
  console.log(typeof a === 'string')
  a = true
  console.log(typeof a === 'boolean')

  a = null
  console.log(a===null) // true
  console.log(typeof a) // 'object'

  console.log('--------------------------------')

  //2. 对象类型
  var b1 = {
    b2: [2, 'abc', console.log],
    b3: function () {
      console.log('b3()')
    }
  }
  console.log(b1 instanceof Object, typeof b1) // true 'object'
  console.log(b1.b2 instanceof Array, typeof b1.b2) // true 'object'
  console.log(b1.b3 instanceof Function, typeof b1.b3) // true 'function'

  console.log(typeof b1.b2[2]) // 'function'
  console.log(b1.b2[2]('abc')) // 'abc' undefined

      1.3 常见问题

  1. undefined与null的区别?
    • 1.undefined是指变量未赋值 var a;
    • 2.null是指定义了变量但是值未null
  2. 什么时候给变量赋值为null呢?
    • 1.指当前变量指向一个对象,但是对象还没有确定
    • 2.对于不要再使用的变量,将其赋值为null,便于垃圾回收器将其回收.
  3. 严格区别变量类型与数据类型?
    • 1.变量类型
      • 1.基本类型:保存基本类型数据的变量
      • 2.引用类型:保存的是对象地址值的变量
    • 2.数据类型
      • 1.基本类型
      • 2.对象(引用)类型

      1.4 访问对象的内部数据或添加属性

    1. .属性名 编码简单,但是有一些场景不能用 ------ xxx.属性名
    • 1.属性名包含-的这种情况.例如:context-type
    • 2.属性名不确定时,例如 propName=‘myage’; …propName=value --错误.
    1. [‘属性名’]都能用 ,但是编码比较麻烦. ----------- xxx[‘属性名’]
  var p = {}
  //1. 给p对象添加一个属性: content type: text/json
  // p.content-type = 'text/json' //不能用
  p['content-type'] = 'text/json'
  console.log(p['content-type'])

  //2. 属性名不确定
  var propName = 'myAge'
  var value = 18
  // p.propName = value //不能用
  p[propName] = value
  console.log(p[propName])

2.函数

      2.1 函数的调用方式

  • 1.直接调用 test()
  • 2.通过对象调用 obj.test()
  • 3.直接new test() 调用
  • 4.test.call() / apply(obj) 让test成为obj对象的临时方法进行调用
  function  test(){
    this.xxx ="wangxxxxx;
  }
  var obj={};

  test.call(obj);
  console.log(obj.xxx);
 
 区别call  和 apply的区别   
 		--call一个或者多个参数
 		--apply 大于一个参数

      2.2 回调函数

  • 定义:
    1.定义了
    2.但是没有调用
    3.最终执行了

  • 常见的回调函数
    1.dom事件回调函数==>发生事件的dom元素
    2.定时器回调函数=>window.
    3.ajax回调函数.
    4.生命周期回调函数.

      2.3 IIFE 立即调用函数表达式

全称: Immediately-Invoked Function Expression
作用:

  1. 隐藏实现
  2. 不会污染外部(全局 )命名空间
  3. 用来编码js代码
  (function () { //匿名函数自调用
    var a = 3
    console.log(a + 3)
  })()
  var a = 4
  console.log(a)

  ;(function () {
    var a = 1
    function test () {
      console.log(++a)
    }
    window.$ = function () { // 向外暴露一个全局函数
      return {
        test: test
      }
    }
  })()

  $().test() // 1. $是一个函数 2. $执行后返回的是一个对象

      2.4 函数中的this

    1. this是什么:
      1.任何函数本质上都是通过某个对象调用的,如果没有直接指定就是window
      2.所有函数的内部都有一个this.
      3.他的值是调用函数的当前对象.
    1. 确定this的值
      1.test() -----window
      2.new person() -----新创建的对象
      3.p.test() ------p
      4.p.call(obj) -----obj
function Person(color) {
    console.log(this)
    this.color = color;
    this.getColor = function () {
      console.log(this)
      return this.color;
    };
    this.setColor = function (color) {
      console.log(this)
      this.color = color;
    };
  }

  Person("red"); //this是谁? window

  var p = new Person("yello"); //this是谁? p

  p.getColor(); //this是谁? p

  var obj = {};
  p.setColor.call(obj, "black"); //this是谁? obj

  var test = p.setColor;
  test(); //this是谁? window

  function fun1() {
    function fun2() {
      console.log(this);
    }

    fun2(); //this是谁? window
  }
  fun1();

2.函数高级

   1.原型与原型链

      1.1 原型

    1. 函数的prototype属性
    • 每个函数都有一个prototype属性, 它默认指向一个Object空对象(即称为: 原型对象)
    • 原型对象中有一个属性constructor, 它指向函数对象
    1. 给原型对象添加属性(一般都是方法)
    • 作用: 函数的所有实例对象自动拥有原型中的属性(方法)
  // console.log(Date.prototype.constructor);  // ---指向Date函数
  // console.log(Date.prototype);
  function Fun() {

  }
  console.log(Fun.prototype);
  Fun.prototype.test=function () {
    alert('测试数据')
  }
  var fun = new Fun();
  fun.test();

      1.2 显示原型(prototype)与隐式原型(__proto __)

每个函数对象中的prototype对应的空对象都是实例对象
每个实例对象中都有一个属性__proto__,对应的是函数对象中的prototype中的实例对象.
javascript_第1张图片

    1. 每个函数function都有一个prototype,即显式原型(属性)
    1. 每个实例对象都有一个__proto__,可称为隐式原型(属性)
    1. 对象的隐式原型的值为其对应构造函数的显式原型的值
    1. 内存结构(图)
    1. 总结:
    • 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象
    • 对象的__proto__属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值
    • 程序员能直接操作显式原型, 但不能直接操作隐式原型(ES6之前)

      1.3 原型链

原型链(图解)

  • 访问一个对象的属性时,
    • 先在自身属性中查找,找到返回
    • 如果没有, 再沿着__proto__这条链向上查找, 找到返回
    • 如果最终没找到, 返回undefined
  • 别名: 隐式原型链
  • 作用: 查找对象的属性(方法)

      1.4 instanceof

  1. instanceof是如何判断的
  • 表达式: A instanceof B
  • 如果B函数的显式原型对象在A对象的原型链上, 返回true, 否则返回false

   2.执行上下文与执行上下文栈

      2.1 变量提升和函数提升

    1. 变量提升
    • 通过var定义(声明)的变量 ,在定义之前就能访问到.
    • 值为undefined
    1. 函数提升
    • 通过function声明的函数,在之前就能够调用
    • 函数定义(对象)
 var a = 3    //undefine
  function fn () {
    console.log(a)   //var a=undefine
    var a = 4
  }
  fn()         输出为 undefine
-------------------------------------
 console.log(b) //undefined  变量提升
 fn2()  //可调用  函数提升
 // fn3() //不能  变量提升
  var b = 3
  function fn2() {
    console.log('fn2()')
  }

var fn3 = function () {
    console.log('fn3()')
  }

注意:函数提升只能用声明的方式才可以 ,变量式的函数不行.

      2.2 执行上下文

  • 分为全局代码和函数代码

    1. 全局执行上下文
    • 在执行全局代码前将window确定为全局执行上下文对象
    • 对全局变量数据进行预处理
      • var定义的全局变量===>undefined , 添加为window属性
      • function声明的全局函数==>赋值(fun) ,添加为window的方法
      • this赋值为 window
    • 开始执行全局代码
  • 2.函数执行上下文

    • 调用函数,准备执行函数体之前,创建对应的函数执行上下文对象(栈中的对象)
    • 对局部数据进行预处理
      • 形参变量=====>赋值(实参)===>添加执行上下文的属性
      • argument====>赋值(实参) ====>添加为执行上下文的属性
      • var 定义为局部变量 ====>undefined,添加为执行上下文的属性
      • function声明的函数====>赋值为(fun) ,添加为执行上下文的方法
      • this====调用函数的对象
    • 开始执行函数体的代码.

      2.23 执行上下文栈

  1. 在全局代码执行前, JS引擎就会创建一个栈来存储管理所有的执行上下文对象
  2. 在全局执行上下文(window)确定后, 将其添加到栈中(压栈)
  3. 在函数执行上下文创建后, 将其添加到栈中(压栈)
  4. 在当前函数执行完后,将栈顶的对象移除(出栈)
  5. 当所有的代码执行完后, 栈中只剩下window

   3.作用域和作用域链

      3.1 作用域与作用域链

  1. 全局作用域
  2. 函数作用域
    作用:不同作用域下同名变量不会冲突
    javascript_第2张图片
 /*
   问题: 结果输出多少?
   */
  var x = 10;
  function fn() {
    console.log(x);
  }
  function show(f) {
    var x = 20;
    f();
  }
  show(fn);             --10

      3.2 作用域与执行上下文

  1. 区别
    1. 全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了。而不是在函数调用时
    1. 全局执行上下文环境是在全局作用域确定之后, js代码马上执行之前创建
    1. 函数执行上下文环境是在调用函数时 , 函数体代码执行之前创建
  1. 区别2
  • 1.作用域是静态的, 只要函数定义好了就一直存在, 且不会再变化
  • 2.上下文环境是动态的, 调用函数时创建, 函数调用结束时上下文环境就会被释放
  1. 联系
    1. 上下文环境(对象)是从属于所在的作用域
    1. 全局上下文环境==>全局作用域
    1. 函数上下文环境==>对应的函数使用域

      3.3 作用域链

  1. 理解
  • 多个上下级关系的作用域形成的链, 它的方向是从下向上的(从内到外)
  • 查找变量时就是沿着作用域链来查找的
  1. 查找一个变量的查找规则
  • 在当前作用域下的执行上下文中查找对应的属性, 如果有直接返回, 否则进入2
  • 在上一级作用域的执行上下文中查找对应的属性, 如果有直接返回, 否则进入3
  • 再次执行2的相同操作, 直到全局作用域, 如果还找不到就抛出找不到的异常

   4.闭包

      4.1 闭包的条件

  1. 当一个嵌套的内部(子)函数引用了外部(父)函数的变量(函数)时,就产生了闭包。
  2. 闭包
  • 闭包是嵌套的内部函数
  • 包含被引用变量(函数)的对象(极少数人)
  function fn1 () {
    var a = 2
    var b = 'abc'
    function fn2 () { //执行函数定义就会产生闭包(不用调用内部函数)
      console.log(a)
    }
    // fn2()
  }
  fn1()

      4.2 常见的的闭包

1.将函数作为另外一个函数的返回值
    function f1(){
      var a=3;
      function f2(){
        a++   //产生闭包
        console.log(a)
      }
      return f2
    }
    var t=f1()   //函数执行完后,进行释放,但是函数内部的变量依然存在可以进行使用
    t();    4  
    t();    5
2.将参数作为实参传递给另外函数调用
    function showDelog(msg,time){
      setTimeout(function () {
        alert(msg);
      },time)
    }
    showDelog('显示数据',2000);

      4.3 闭包的作用

  1. 可以让函数内部的局部变量在函数执行完后,依然存活在内存中(延迟局部变量的声明周期)
  2. 可以让函数外部操作函数内部的数据.

1.函数执行完后,函数内部声明的局部变量是否还存在? 一般不存在,存在于函数内部的闭包可能存在
2.函数外部能够访问到函数的局部变量吗? 不能,但是我们可以通过闭包去访问.

      4.4 闭包的生命周期

  1. 产生: 在嵌套内部函数定义执行时,闭包就产生了.
  2. 死亡:在嵌套的内部函数为垃圾对象被回收时,闭包就死亡了(其实就是闭包所在的函数为垃圾对象)
    function f1(){             //执行函数时,闭包产生
      var a=3;
      function f2(){
        a++   //产生闭包
        console.log(a)
      }
      return f2
    }
    var t=f1()   
    t();    4  
    t();    5
    t=null   //当调用函数对象没人调用时,变为垃圾对象时闭包就死亡了.

      4.5 闭包的应用-自定义JS模块

  1. JS模块其实具有特定功能的js文件
  2. 将所有的数据和功能封装到一个函数内部(私有的)
  3. 向外暴漏一个(多个方法)对象 或者 函数.
  4. 模块的使用者只需要执行暴漏出来的相应方法进行执行.
第一种方式:
  (function () {
      var msg='mybatis';
      function f1() {
         console.log(msg)
      }
      window.moudle={
        f1:f1
      }
  })()
  
 第二种方式:
    function  f1()  {
      var msg='mybatis';
      function f2() {
         console.log(msg)
      }
      return f2
  }
var t=f1()
t();  //执行闭包

      4.6 闭包的缺点

  1. 内存溢出:
    • 指的是程序运行所需要的内存超过了系统所拥有的内存.
    • 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
  2. 内存泄漏:指的是一段内存
    • 占用的内存没有来的及释放
    • 占用的内存太多容易导致内存溢出
    • 常见的内存泄漏: 1.意外的全局变量. 2.没有及时清除计时器或者回调函数 3.闭包
function f1(){
	a=3 				  //1.意外的全局变量
}
f1();

var intervalId= setInterval(function(){
	console.log('--------')
},1000)  			//2.计时器没来得及清除
clearInterval(intervalId);

  function fn1() {
    var a = 4
    function fn2() {
      console.log(++a)   // 3. 闭包
    }
    return fn2
  }
  var f = fn1()
  f()

4.对象高级

   1.对象创建模式

      1.1 Object构造函数模式

  • 套路: 先创建空Object对象, 再动态添加属性/方法
  • 适用场景: 起始时不确定对象内部数据
  • 问题: 语句太多
var t=new Object()
  t.name='xxx'
  t.age=12
  t.setName=function (name) {
    this.name=name
  }

  console.log(t.name,t.age)
  t.setName('bob')
  console.log(t.name,t.age)

      1.2 对象字面量

  • 套路: 使用{}创建对象, 同时指定属性/方法
  • 适用场景: 起始时对象内部数据是确定的
  • 问题: 如果创建多个对象, 有重复代码
var obj={
    name:'xxxx',
    age:12,
    setName :function (name) {
      this.name=name
    }
  }

  console.log(obj.name,obj.age)
  obj.setName('wx')
  console.log(obj.name,obj.age)

       1.3 工厂模式

  • 套路: 通过工厂函数动态创建对象并返回
  • 适用场景: 需要创建多个对象
  • 问题: 对象没有一个具体的类型, 都是Object类型
   function createPerson(name ,age){
     var obj={
       name:name,
       age:age,
       setName:function (name) {
         this.name=name
       }
     }
     return obj;
   }
   
   var person1=createPerson('xxxx',12);
   var person2=createPerson('bbbb',18);

       1.4 自定义构造函数

  • 套路: 自定义构造函数, 通过new创建对象
  • 适用场景: 需要创建多个类型确定的对象
  • 问题: 每个对象都有相同的数据, 浪费内存
  function Person(name,age) {
    this.name=name;
    this.age=age;
    this.setName=function (name) {
      this.name=name
    }
  }
  var p1=new Person('wx',18);
  p1.setName('bob')
  console.log(p1.name,p1.age);
  console.log(p1 instanceof Person)

       1.5 构造函数+原型的组合模式

  • 套路: 自定义构造函数, 属性在函数中初始化, 方法添加到原型上
  • 适用场景: 需要创建多个类型确定的对象
  function Person(name ,age){
   this.name=name
    this.age=age
 }
  Person.prototype.setName= function (name) {
  this.name =name
 }

var p1 =new Person('xxx',18);
p1.setName('xxx1')
var p2=new Person('bob',20);
p2.setName('bob1')

console.log(p1.name,p1.age)
console.log(p2.name,p2.age)

   2.继承模式

       2.1 原型链继承

其实关键在于子类型的显示原型是父对象的实例对象.
javascript_第3张图片

//父类型
  function Supper() {
    this.supProp = 'Supper property'
  }
  Supper.prototype.showSupperProp = function () {
    console.log(this.supProp)
  }
 //子类型
  function Sub() {
    this.subProp = 'Sub property'
  }
//子类型的显示原型为父类的实例对象   --
Sub.prototype = new Supper()
// 让子类型的原型的constructor指向子类型
Sub.prototype.constructor=Sub

       2.2 借用构造函数继承

其实就是调用call

  function Supper(name ,age){
    this.name =name
    this.age =age
  }
  function Sub(name,age,price){
    Supper.call(this,name,age)  //相当于 创建对象的t   t.Supper(name ,age)  ----t.name ,t.age
    this.price=price
  }
  var t=new Sub('wwd',18,120)
  console.log(t.name,t.age,t.price);

       2.3 组合继承

继承分为两种 ,一种是原型链继承,一种是借用构造函数继承。原型链主要是用来继承prototype的方法,而借用构造函数主要继承的是属性。所有需要结合两种方式的去实现继承。

 function Person(name ,age){
      this.name =name
      this.age=age
  }
  Person.prototype.setName =function (name) {
      this.name=name
  }

  //借用构造函数继承
  function Student(name ,age, price) {
      Person.call(this,name,age)
      this.price=price
  }
  //原型链继承
  Student.prototype =new Person()
  Student.prototype.constructor=Student

  var t=new Student('wwd',18,1000)
  t.setName('wwd1')
  console.log(t.name,t.age,t.price);

5.线程机制与事件机制

   1.1 进程与线程

   1.2 浏览器内核

   1.3 定时器

   1.4 JS是单线程

   1.5 进程与线程

   1.6 事件循环模型

   1.7 Web Workers

语句括号问题

  • 小括号开头的前一句语句
  • 中方括号开头的前一条语句

你可能感兴趣的:(前端,javascript,学习,前端)