第六周 JS 学习笔记

这周天气开始回暖,课上大家都很犯困,可能是讲的内容比较晦涩难懂吧

一、函数

1)模仿块级作用域

  • 自调用函数
  1. 写法
(function(){})()
(function(){}())
  • 沙箱模式模仿块级作用域
function outputNumbers(count){
      (function(){
          for(var i=0; i< count; i++){
              console.log(i)
          }
      })()
      console.log(i)    // 报错
  }

在外部环境中无法访问沙箱环境中的任何数据,但是由于在沙箱中this指向全局,故可以修改外部的数据

2)递归

  • 典型递归
function factorial(num){
      if(num <= 1){
          return 1
      }else {
          return num * factorial(num -1)
      }
  }
  • 使用callee实现
function factorial(num){
      if(num <= 1){
          return 1
      }else {
          return num*arguments.callee(num-1)
      }
  }
  • 解耦函数名,隔离
 var factorial = (function f(num){
      if(num <= 1){
          return 1;
      }else {
          return num * f(num-1)
      }
  })

3)闭包

  • 引用外部数据
 function foo(name){
      return function(){
          console.log(name)
      }
  }

** 导致数据被缓存,无法释放

  • 利用闭包解决引用问题
  function createFunction(){
      var result = new Array();
      for(var i=0; i<10; i++){
          result[i] = function (num){
            return function(){
                return num;  // 引用num 导致num无法释放
            }
          }(i)
      }
      return result;
  }
  • 闭包产生的this 指向问题
  var name = 'The window';
  var obj ={
      name: 'my obj',
      getNameFunc: function(){
          return function(){
              return this.name
          }
      }
  }
  console.log(obj.getNameFunc()())   // The window
  // 导致this指向全局的原因: 每个函数在被调用时都会自动取得两个特殊变量this和arguments ,
  // 内部函数在搜索这两个变量的时候,只会搜索到其活动对象为止

4)私有变量

  • 模块模式
 var singleton = function (){
      var privateVariable = 10;
      function privateFunc(){
          return false;
      }
      // 创建对象
      var object = new CustomType();
      // 特权,公有方法和属性
      object.publicProperty = true;
      object.publicMehod = function(){
          privateVariable++;
          return privateFunc()
      }
      return object;
  }()

此方法,内部的私有变量和方法得以保护,外界无法通过singleton变量访问

二、面向对象

1)属性类型

  • 数据属性
   * Configurable 是否可配置
   * Enumerable 是否可枚举
   * Writable 是否可修改
   * Value 属性的数据值
  • 修改属性的默认特性
  var o =  {};
   Object.defineProperty(o,'name',{
       value: '中国',
       writable: false
   })
  o.name = '美国'
  console.log(o.name)
  • 访问器属性
var book ={
      _year: 2001,
      edition: 1
  };
  Object.defineProperty(book, 'year',{
      get: function(){
          return this._year
      },
      set: function(newVal){
          if(newVal > this._year){
              this._year = newVal;
              this.edition += newVal - 2001;
          }
      }
  })
  book._year = 2002;
  console.log(book.edition)
  console.log(book._year)

调用 get 和 set 两个存取器方法 ,能够限制修改属性的值

  • 定义多个属性的特性
  var o2 = {}
  Object.defineProperties(o2,{
      _year: {
          writable:true,
          value: 2004
      },
      edition: {
          writable: true,
          value: 1
      },
      year: {
          get: function(){},
          set: function(){}
      }
  })
  • 读取属性的特性
var descriptor = Object.getOwnPropertyDescriptor(book,"year")

2)创建对象

构造函数 + 原型模式

 function Mode(name, age, job){
      this.name = name;
      this.age = age;
      this.job = job;
  }
  Mode.prototype = {
      constructor: Mode,
      sayName: function(){
          console.log(this.name)
      }
  }
  var mode = new Mode('Nick', 30, 'software')
  • in 操作符 判断是否是可访问的属性
var o5 = {
      name: '张三'
  }
  console.log("name" in o5)
  • for-in 遍历所有可访问的属性
 function Animal(name){
      this.name
  }
  Animal.prototype.size = 23;
  var animal = new Animal('狮子')
  animal.sex = '公'
  for(var prop in animal){
      console.log(prop)
  }
  • Object.keys()
console.log(Object.keys(animal))

返回所有可枚举的实例属性的一个字符串数组, 不会遍历到原型上

  • Object.getOwnPropertyNams
console.log(Object.getOwnPropertyNames(Animal.prototype))

此方法用于获取所有实例的属性,不管是否可枚举

3)继承

  • 组合继承
    组合继承 首先会使用对象冒充的方式去继承父类构造函数中的属性,接着通过对子类的prototype.constructor设置进行构造器校正。
 function SuperType(name){
      this.name = name;
      this.colors = ['red','blue','green']
  }
  SuperType.prototype.sayName = function(){
      console.log(this.name)
  }
  function SubType(name,age){
      //继承属性
      SuperType.call(this, name);
      this.age =  age;
  }
  // 继承方法
  SubType.prototype = new SuperType()
  SubType.prototype.constructor = SubType;
  SubType.prototype.sayAge= function(){
      console.log(this.age)
  }
  • 寄生组合式继承
function inheritPrototype(subType,superType){
      var prototype = Object.create(superType.prototype);
      prototype.constructor = subType;
      subType.prototype = prototype;
  }
  function SuperType(name){
      this.name = name;
      this.colors = ['red','blue','green']
  }
  SuperType.prototype.sayName = function(){
      console.log(this.name)
  }
  function SubType(name,age){
      SuperType.call(this,name);
      this.age =  age;
  }
  inheritPrototype(SubType,SuperType);

  var subtype = new SubType('张三', 23)
  subtype.sayName();  // 张三

你可能感兴趣的:(第六周 JS 学习笔记)