认识对象

  1. 认识对象
    • 对象(object) 是键值对的集合,表示属性和值的映射关系
    • 对象的语法:k和v之间用冒号分割,每组k:v之间用逗号分割,最后一个k:v对后可以不书写逗号
    • 属性名是否加引号?:如果对象的属性名不符合JS标识符命名规范,则这个键名必须用引号包裹
    • 属性的访问:可以用“点语法”访问对象中指定键的值,如果属性名不符合JS标识符命名规范,则必须用方括号的写法来访问;如果属性名以变量形式存储,则必须使用方括号形式
    • 属性的更改:直接使用赋值运算符对某属性复制即可更改属性
    • 属性的创建:如果对象本身没有某个属性值,则用点语法赋值时,这个属性就会被创建出来
    • 属性的删除:如果要删除某个对象的属性,则需要用delete操作符
  2. 对象的方法
    • 如果某个属性值是函数,则它也被称之为对象的“方法”
    • 方法也是函数,只不过方法是对象的“函数属性”,它需要对象打点使用
  3. 对象的遍历
    • 和遍历数组类似,对象也可以被遍历,遍历对象需要使用 for…in….循环
    • 使用 for…in…循环、Object.keys() 等 可以遍历对象每个键
  4. 对象的深浅克隆(面试)
    • 基本类型值和引用类型值
      • 基本类型值
        • 数字、字符串、布尔、undefined、null
        • 内存中产生新的副本
        • 比较值是否相等
      • 引用类型值
        • 对象、数组等
        • 内存中不产生新的副本,而是让变量指向同一个对象
        • 比较内存地址是否相同,即比较是否为同一对象
    • 对象也是引用类型值
      • 不能通过var obj2 = obj1 这样的语法克隆一个对象
      • 使用 == 或者 === 进行对象的比较时,比较的是它们是否为内存中的同一个对象,而不是比较值是否相同
    • 浅克隆:只克隆对象的“表层”,如果对象的某些属性值又是引用类型值,则不进行一步克隆它,而是引用它
    • 对象的深克隆:克隆对象的全貌,无论对象的属性值是否又是引用类型值,都能将它们实现克隆
    • 和数组的深克隆类似,对象的深克隆需要使用递归

认识函数的的上下文

  1. 什么是上下文
    • 函数的上下文:函数中可以使用 this 关键字,它表示函数的上下文
    • 与中文中“这”类似,函数中的 this 具体指代什么必须通过调用函数时的“前言后语”来判断
    • 普通函数的上下文是调用使用才能确定的,并且规则很多,但是箭头函数的上下文是定义时候确定的。
    • 函数的上下文由调用方式决定
      • 同一个函数,用不同的形式调用他,则函数的上下文不同
      • 函数只有被调用的时候,它的上下文才能被确定
      • 函数的上下文(this关键字)由调用函数的方式决定,function是“运行时上下文”策略
      • 函数如果不调用,则不能确定函数的上下文
  2. 6种上下文规则
    • 规则1:对象打点调用它的方法函数,则函数的上下文是这个打点的对象
      • 对象.方法()
    • 规则2:圆括号直接调用函数,则函数上下文是window对象
      • 函数()
    • 规则3:数组(类数组对象)枚举出函数进行调用,上下文是这个数组(类数组对象)
      • 数组下标
      • 类数组对象
        • 什么是类数组对象:所有键名为自然数序列(从0开始),且有length属性的对象
        • argument对象是最常见的类数组对象,它是函数的实参列表
    • 规则4:IIFE中的函数,上下文是window对象
      • IIFE:立即可执行函数
      • (function(){ ... })()
    • 规则5:定时器、延时器调用函数,上下文是window对象
      • setInterval(函数,时间)
      • setTimeout(函数,时间)
    • 规则6:事件处理函数的上下文是绑定事件的DOM元素
      • DOM元素.onclick = function(){ ... }
  3. call和apply (call 呼叫,打电话,apply 应用,申请)
    • call 和 apply 能指定函数的上下文
      • 函数.call(上下文)
      • 函数.apply(上下文)
    • call 和 apply 区别
      • 只有在函数有参数的时候才能被体现出来
      • 1、call 要用逗号罗列参数 ;2、apply 要把参数写到数组中
  4. 上下文规则总结(规则/上下文)
    • 对象.函数()
      • 对象
    • 函数()
      • window
    • 数组下标
      • 数组
    • IIFE
      • window
    • 定时器、延时器
      • window
    • DOM事件处理函数
      • 绑定DOM的元素
    • call 和 apply
      • 任意指定
    • 用 new 调用函数
      • 秘密创建出的对象

构造函数

  1. 用new调用函数四布走
    • 用 new 调用函数的执行步骤和它的上下文弄清楚
    • JS 规定,使用new操作符调用函数会进行“四步走”:
      • 1、函数体内会自动创建出一个空白对象
      • 2、函数的上下文(this)会指向这个对象
      • 3、函数体内的语句会执行
      • 4、函数会自动返回上下文对象,即使函数没有return语句
  2. 构造函数
    • 构造函数是一种特殊类型的函数,它在创建对象时被调用。它的主要目的是初始化对象的属性和方法。在JavaScript中,构造函数通常使用关键字classfunction定义,并使用new关键字来创建对象。构造函数可以接受参数,这些参数可以用于设置对象的属性。
  3. 类和实例
    • 类好比是“蓝图”,类只描述对象会拥有哪些属性和方法,但是并不具体指明属性的值。
    • 实例是具体的对象
    • JavaScript中的构造函数可以类比于OO语言中的“类”,写法的确类似,但和真正的OO语言还是有本质的不同

原型和原型链

  1. 继承
    • 实现继承的关键在于:子类必须拥有父类的全部属性和方法,同时子类还能定义自己特有的属性和方法。
    • 1、原型链继承
      • 使用方法:
        • 子类的 prototype (原型) = new 父类()
        • 让子类的构造函数的 prototype ,指向父类的一个实例
        • 使用 Javascript 特有的原型链特性来实现继承,是普遍的做法
      • 存在的问题:
        • 问题2:子类的构造函数中,往往需要重复定义很多超类(父类、基类)定义过的属性,即,子类的构造函数写的不够优雅
        • 问题1:如果父类的属性中有引用类型值,则这个属性会被所有子类的实例共享
      • 代码示例
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        function Parent() {
        this.name = 'Parent';
        }
        Parent.prototype.sayHello = function() {
        console.log('Hello from Parent');
        };
        function Child() {

        }
        Child.prototype = new Parent();
        var child = new Child();
    • 2、构造函数继承(伪造对象、经典继承)
      • 使用方法:
        • Parent.call(this, name);
      • 存在的问题:
        • 借用构造函数的思想非常简单:在子类构造函数的内部调用超类的构造函数,但是要注意使用 call() 绑定上下文
      • 代码示例
        1
        2
        3
        4
        5
        6
        7
        function Parent(name) {
        this.name = name;
        }
        function Child(name) {
        Parent.call(this, name);
        }
        var child = new Child('Child');
    • 3、组合继承
      • 使用方法:
        • Parent.call(this, name);
        • Child.prototype = new Parent();
      • 存在问题:
        • 将借用原型链和借用构造函数的技术组合到一起,叫做组合继承,也叫做伪经典继承
        • 组合继承是 JavaScript 中最常用的继承方式
        • 组合继承继承的问题:组合继承最大的问题就是无论在什么情况下,都会调用两次超类的构造函数:一次是在创建子类原型的时候,另一次是在子类构造函数的内部
        • 构造函数继承和组合继承的区别在于: - 构造函数继承通过在子类构造函数内部调用父类构造函数来实现属性的继承,但无法继承父类原型链上的方法。 - 组合继承则是结合了原型链继承和构造函数继承的优点,通过调用父类构造函数来实现属性的继承,并且通过将子类的原型指向父类的实例来继承父类的方法。
      • 代码示例
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        function Parent(name) {
        this.name = name;
        }
        Parent.prototype.sayHello = function() {
        console.log('Hello from ' + this.name);
        };
        function Child(name, age) {
        Parent.call(this, name);
        this.age = age;
        }
        Child.prototype = new Parent();
        var child = new Child('Child', 10);
    • 4、原型式继承
      • 使用方法:
        • var child = Object.create(parent);
      • 存在问题:
        • Object.create() 方法,可以根据指定的对象为原型创建出新对象,兼容性大于IE9
        • 在没有必要“兴师动众”地创建构造函数,而只是想让新对象与现有对象“类似”的情况下,使用 Object.create() 即可胜任,称为原型式继承
        • Object.create() 的兼容性写法
          • 如何在低版本浏览器中实现 object.create() 呢?
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
              function object(o) {
            // 创建一个临时构造函数
            function F() { }
            // 让这个临时构造函数的 prototype 指向o,这样一来它 new 出来的对象,__prototype__ 指向了o
            F.prototype = o
            // 返回 F 的实例
            return new F();
            }
            var obj1 = {
            a: 1,
            b: 2,
            c: 3,
            test: function () {
            return this.a + this.b
            }
            }
            var obj2 = object(obj1)
            console.log(obj2.__proto__ === obj1) // true
            console.log(obj2.a)
            console.log(obj2.b)
      • 代码示例
        1
        2
        3
        4
        5
        6
        7
        var parent = {
        name: 'Parent',
        sayHello: function() {
        console.log('Hello from Parent');
        }
        };
        var child = Object.create(parent);
    • 5、寄生式继承
      • 使用方法:
        • 编写一个函数,它接收一个参数o,返回以o为原型的新对象p,同时给p上添加预置的新方法
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
            var o1 = {
          name: '小明',
          age: 16,
          arr: [1, 2, 3]
          }
          var o2 = {
          name: '悠悠',
          age: 16,
          arr: [1, 2, 3]
          }

          function f(o) {
          var p = Object.create(o)
          p.sayHello = function () {
          console.log(`你好,我是${this.name},今年${this.age}岁`)
          }
          p.sleep = function () {
          console.log(`${this.name},正在睡觉`)
          }

          return p
          }
          var p1 = f(o1)
          p1.arr.push(88)
          p1.sayHello()

          var p2 = f(o2)
          p2.sayHello()
          console.log("p2",p2)
        • 寄生式继承就是编写一个函数,它可以“增强对象”,只要把对象传入这个函数,这个函数将以此对象为“基础”创建出新对象,并为新对象赋予新的预置方法
        • 在主要考虑对象而不是自定义类型和构造函数的情况下,寄生式继承也是一种有用的模式
      • 存在问题:
        • 缺点:使用寄生式继承来为对象添加函数,会由于不能做到函数复用而降低效率,即“方法没有写到 prototype 上”
      • 代码示例
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
         function createChild(obj) {
        var child = Object.create(obj);
        child.sayHi = function() {
        console.log('Hi from Child');
        };
        return child;
        }
        var parent = {
        name: 'Parent',
        sayHello: function() {
        console.log('Hello from Parent');
        }
        };
        var child = createChild(parent);
    • 6、寄生组合式继承
      • 使用方法:
        • 基本思路:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已,本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          // 这个函数接受两个函数,子类构造函数、父类构造函数
          function inheritPrototype(subType, superType) {
          var prototype = Object.create(superType.prototype)
          subType.prototype = prototype;
          }


          function People(name, sex, age) {
          this.name = name;
          this.age = age;
          this.sex = sex;
          this.arr = [33, 44, 56]
          }

          People.prototype.sayHello = function () {
          alert('hello 我是' + this.name)
          }

          People.prototype.sleep = function () {
          alert(this.name + '在睡觉')
          }

          function Student(name, sex, age, no, scholl) {
          People.call(this, name, sex, age)
          this.no = no;
          this.scholl = scholl;
          }

          // 调用我们自己写的 inheritPrototype 函数,让 Student 类的 prototype 指向以 People.prototype 为原型的一个新对象
          inheritPrototype(Student, People)

          Student.prototype.study = function () {
          console.log(this.name + '正在学习')
          }

          Student.prototype.exam = function () {
          console.log(this.name + '正在考试')
          }


          var xiaoming = new Student('小明', '男', '0', 14025123, 'wenzhou')

          xiaoming.sayHello()
        • 通过借用构造函数来继承属性,通过原型链的混成形式来继承方法
      • 存在问题:
        • 寄生组合式继承的主要缺点是: 1. 虽然解决了组合继承中多次调用父类构造函数的问题,但仍然会调用一次父类构造函数来创建原型。 2. 增加了代码的复杂度,相比其他继承方式,可读性较差。
      • 代码示例
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        function inheritPrototype(Child, Parent) {
        var prototype = Object.create(Parent.prototype);
        prototype.constructor = Child;
        Child.prototype = prototype;
        }
        function Parent(name) {
        this.name = name;
        }
        Parent.prototype.sayHello = function() {
        console.log('Hello from ' + this.name);
        };
        function Child(name, age) {
        Parent.call(this, name);
        this.age = age;
        }
        inheritPrototype(Child, Parent);
        var child = new Child('Child', 10);
    • instanceof 运算符
      • 用来检测“某个对象”对象是不是某个类的实例
      • 底层机理:检查 Student.prototype 属性是否在 xiaoming 的原型链上(多少层都是,只要在就行)
        1
        xiaoming instaceof Student
  2. 原型链的终点
    • 原型链的终点是 Object.prototype。 Object.prototype 是所有 JavaScript 对象的顶层原型,它是原型链的终点。
  3. 在prototype上添加方法
    • People.prototype.方法 = function(){ … }
  4. prototype在原型链查找
    • Javascript规定:实例可以打点访问它的原型的属性和方法,这被称为“原型链查找”
    • 遮蔽效应:如果实例上已经有属性和方法,则不往原型链上查找
  5. 什么是prototype?
    • 任何函数都有prototype属性,prototype是英语“原型”的意思
    • prototype 属性值是个对象,它默认拥有 constructor 属性指回函数
    • 普通函数的 prototype 属性没有任何用处,而构造函数的 prototype 属性非常有用
    • 构造函数的 prototype 属性是它实例的原型
  6. hasOwnProperty
    • hasOwnProperty 方法可以检查对象是否真正“自己拥有”某属性或者方法
      • 实例.hasOwnProperty(‘属性|方法’)
  7. in
    • in 运算符只能检查某个属性或方法是否可以被对象访问,不能检查是否自己的属性或方法
      • 语法:’属性|方法’ in 实例

上升到面向对象

  1. 面向对象的本质:定义不同的类,让类的实例工作
  2. 面向对象的优点:程序编写更清晰、代码结构更严密、使代码更健壮更利于维护
  3. 面向对象经常用到的场合:需要封装和复用性的场合(组件思维)

JS的内置对象

  1. Date对象
    • 使用 new Date() 即可得到当前时间的日期对象,它是 object 类型值
    • 使用 new Date(2020,11,1) 即可得到指定日期的日期对象,注意第二个参数表示月份,从0开始算,11表示12月
      • 这种写法不算时区
    • 也可以是 new Date(‘2020-12-01’) 这样的写法,月份,日期不足两位要补零
      • 按照字符串的写法,月份不是从0开始算,12月就是12月
      • 这种写法算时区,中国属于东八区
    • 日期对象的常见方法
      • getDate() 得到日期 1 ~ 31
      • getDay() 得到星期 0 ~ 6
      • getMonth() 得到月份 0 ~ 11
      • getFullYear() 得到年份
      • getHours() 得到小时数 0 ~ 23
      • getMinutes() 得到分钟数 0 ~ 59
      • getSeconds() 得到秒数 0 ~ 59
    • 时间戳
      • 时间戳表示1970年1月1日零点整距离某时刻的毫秒数
      • 通过 getTime() 方法或者 Date.parse() 函数可以将日期对象变为时间戳
        • getTime() 精确到毫秒
        • Date.parse() 精确到秒
      • 通过 new Date(时间戳) 的写法,可以将时间戳变为日期对象
  2. 包装类
    • Number()、String()、Boolean() 分别是数字、字符串、布尔值的“包装类”
    • 很多编程语言都有“包装类”的设计,包装类的目的就是为了让基本类型值可以从他们的构造函数的prototype上获得方法
    • Number()、String()、Boolean() 的实例都是 object 类型,它们的 PrimitiveValue 属性存储的它们本身值
      • PrimitiveValue 属性不可以自己打点访问,它是一个内部属性值
    • new 出来的基本类型值可以正常参与运算
    • Array 不能成为数组的包装类 ,包装类是对基本类型的面向对象封装,而 Array 本身就不是基本类型值(而是引用类型值),所以就谈不上包装了,undefined、null 是没有包装类的
  3. Math对象
    • 幂和开方
      • Math.pow()、Math.sqrt()
    • 向上取整和向下取整
      • Math.ceil()、Math.floor()
    • 四舍五入方法
      • Math.round()
    • Math.max() 和 Math.min()
      • Math.max() 可以得到参数列表最大值
      • Math.min() 可以得到参数列表最小值
      • Math.max() 要求参数必须是“罗列出来”,而不能是数组
        • 用 ES6 展开运算符
        • Math.max.apply(null,arr)
    • 随机数 Math.random()
      • Math.random() 可以得到 0 ~ 1之间的小数
      • 为了得到 [a,b] 区间内的整数,可以使用这个公式
        • parseInt(Math.random() * (b - a + 1)) + a

JS的内置构造函数

  1. Javascript 有很多内置构造函数,比如Array就是数组的构造函数,Function 就是函数类型的构造函数,Object 就是对象类型的构造函数
    • 任何数组的字面量都可以看做是Array的实例
    • 拓展数组的求和方法
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      // 拓展求和方法
      Array.prototype.sum = function () {
      var arr = this;
      console.log(this)
      var count = 0;
      for (let i = 0; i < arr.length; i++) {
      count += arr[i]
      }
      return count
      }
      var arr = [1, 3, 4];
      console.log(arr.sum())
  2. 内置的构造函数非常有用,所有该类型的方法都是定义在它的内置构造函数的 prototype 上的,我们可以给这个对象添加新的方法,从而拓展某类型的功能
  3. 内置构造函数的关系
    • Object.prototype 是万物原型链的终点。Javascript 中函数、数组皆为对象。
    • 任何函数都可以看做是 Function “new 出来的”,那我们开一个脑洞:Object 也是函数呀,它是不是 Function “new 出来的呢”?答案是肯定的

** *重点内容 **

  1. 熟悉每条函数上下文 this 的判定规则
    • 函数上下文 this 取决于函数如何被调用,而不是函数如何被定义
  2. call 和 apply 的功能和区别
  3. 用 new 调用函数的四步走
  4. 什么是类和实例?面向对象编程的意义
  5. prototype 和原型链查找
  6. 继承的实例、有哪些继承的方法?
  7. 使用面向对象实现小案例
  8. 熟练掌握 Math、Date等 JS 内置对象

条件语句

  1. if 语句的基本使用
    • 如果…..就…..否则
  2. if elseif 多条件分支
    • else if() 条件分支“暗含”不符合之前的所有条件,要深刻理解什么叫“否则如果”
  3. if 语句算法题
  4. switch 语句
    • 用途:当一个变量被分类讨论的情形
  5. 三元运算符
    • 条件表达式 ? 表达式1 : 表达式2
    • 三元运算的用途:根据某个条件是否成立,在两个不同值中选择变量的值

循环语句

  1. for 循环语句
    • 循环通常需要三个参数:起始值、结束值和步长。这些参数可以用for循环来指定。
  2. for 循环算法题
    • for循环有明确的范围,while循环没有明确的范围
  3. while 循环语句
    • while 语句 也是一种循环结构,是一种“不定范围”循环,和for循环各有不同的勇武之地
    • 几乎所有编程语言,都提供了for和while语句
    • while 语句事先不指定循环开始、结束范围,只要测试条件满足,就一直执行循环体
    • while 循环没有显式定义循环变量,必须自己在while循环外先定义好循环变量,有时甚至可以没有循环变量
    • 循环体内的语句,必须使循环测试条件趋向不成立,否侧会死循环。
    • while 循环,while 是 “当”的意思。
    • 更适合while循环的场景
      • 寻找最小满足n²>456789的整数n
  4. break 和 continue
    • break 表示立即终止循环,它只能用在循环语句中,在for循环和while循环中都可以使用
    • continue 用于 跳过循环中的一个迭代,并继续执行循环中的下一个迭代。for循环更经常使用continue
  5. do while 语句
    • 是一种“后测试循环语句”,它不同于for循环和while循环每次都是“先测试条件是否满足,然后执行循环体”,do-while循环是“先执行循环体,再测试条件是否满足”
    • do { 循环体 } while (循环执行条件)
  6. while 语句算法题

初识算法

  1. 什么是算法
    • 指的是解题方案的准确而完整的描述。是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制,也就是说,能够对一定规范的输入,在有限的实际内获得所要求的的输出。
    • 算法就是把一个问题,拆解成计算机能够一步一步执行的步骤。
    • 计算机的流程控制语句:顺序执行,选择语句,循环语句。
    • 优秀算法的要求
      • 正确性
      • 健壮性
      • 可读性
  2. 累加器和累乘器
  3. 穷举法
  4. 综合算法题目
  5. 随机数函数
    • 得到[a,b]区间的整数,公式:
    • parseInt(Math.random()* (b-a + 1)) + a

如何拆位

  1. 数学方法
    • 百位是原数字除以100取整 Math.floor(n/100)
    • 十位是原数字除以10取整,再与10求模 Math.floor(n/10) % 10
    • 个位是原数字与10求模 n % 10
  2. 字符串方法
    • 直接将原数字 变为字符串,然后再用charAt()方法得到每个数位的值

定时器

  1. setInterval() 函数可以重复调用一个函数,在每次调用之间具有固定的时间间隔
    • 第一个参数是函数
    • 第二个参数是间隔时间,以毫秒为单位,1000毫秒是1秒
    • 函数可以接受3,4….个参数,它们将按照顺序传入函数
    • 具名函数也可以传入serInterval (有名称的函数),但是不能加上括号,不加括号说明传入是 函数,加括号说明是传入执行体(会立即执行,起不到定时执行的效果)

清除定时器

  1. clearInterval() 函数可以清除定时器,入参传入定时器名称

延时器

  1. setTimeout() 函数可以设置一个延时器,当指定时间到了之后,会执行函数一次,不会重复执行
  2. clearTimeout() 函数可以清除延时器

初步认识异步语句

  1. setInterval 和 setTimeout 是两个异步语句
  2. 异步(asynchronous): 不会阻塞CPU继续执行其它语句,当异步完成时,会执行“回调函数”(callback)

使用定时器实现动画

  1. 使用定时器实现动画较为不便:
    • 1、不方便根据动画总时间计算步长
    • 2、运动方向要设置正负
    • 3、多种运动进行叠加较为困难(比如一个放下一边移动一边变为圆形)

JS和CSS3结合实现动画

  1. CSS3的transition过渡属性可以实现动画
  2. JavaScript可以使用css3的transtion属性轻松实现元素动画
  3. JS和CSS3结合实现动画规避了定时器制作动画的缺点

函数节流

  1. 一个函数执行一次后,只有大于设定的执行周期后才允许执行第二次
  2. 函数节流非常容易实现,只需要借助setTimeout()延时器

JS 基本表达式

  1. 算数表达式
    • + 加
      • 加号有“加法”和“连字符”两种作用
      • 如果加号两边操作数都是数字,则为“加法”,否则为连字符
    • - 减
    • * 乘
    • / 除
    • % 取余
      • a % b 表示求 a 除以 b 的余数,它不关心整数部分,只关心余数
    • 默认情况,乘除法的优先级要高于加法和减法;必要时可以使用圆括号来改变运算的顺序
    • 隐式类型转换
      • 如果参与数学运算的某操作数不是数字型,那么Javascript会自动将此操作数转换为数字型(不包括 加号 运算符)
      • 例:3 * "4" // 12
      • 隐式转换的本质是内部调用 Number() 函数
  2. 关系表达式
    • 大于 >
    • 小于 <
    • 大于或等于 >=
    • 小于或等于 <=
    • 等于 ==
    • 不等于 !=
    • 全等于 ===
    • 不全等于 !==
    • null 和 undefined 用 == 进行比较涉及隐式强制类型转换,ES5规范中规定
      • 如果 x 为null ,y为 undefined,则结果为true
      • 如果x为undefined,y为null,则结果为true
      • null 和 undefined 用 === 比较时结果为false,是因为类型不同
      • typeof null -> object
      • typeof undefined -> undefined
    • NaN 不自等
      • 如何判断某个值为 NaN ,isNaN
  3. 逻辑表达式
      • || 有真就真
      • && 都真才真
      • ! 表示 “非”,也可以称为“置反运算”
      • ! 是一个“单目运算符”,只需要一个操作数
      • 置反运算的结果一定是布尔值
      • !! 两个叹号是将这个值的相应布尔值展现出来
    • 短路计算(面试)
      • 例:3 && 6 ,结果为 6, 3 || 6 ,结果为 3
    • 逻辑运算顺序的优先级是: 非 -> 与 -> 或
  4. 赋值表达式
    • 赋值 =
    • 快捷赋值
      • +=
      • -=
      • *=
      • /=
      • %=
    • 自增运算
      • ++
      • a++ 先用再加,++a 先加再用
      • 面试题:var a = 3, b=4; alert(a++ + b++ + ++a + ++b)
    • 自减运算 –
  5. 综合表达式
    • 运算顺序:非运算 -> 数学运算 -> 关系运算 -> 逻辑运算
    • 变量的范围表示
      • 例如:验证变量 a 是否介于5到12之间。num1 >= 5 && num1 <= 12

表达式和运算符

  1. 5 + 3
    • 表达式 = 操作数 运算符 操作数

有关 IEEE754

  1. Javascript 使用了 IEEE754 二进制浮点数算数标准,这会使一些个别的小数计算产生“丢失精度”问题
  2. 解决方法:在进行小数运算时候,要调用数字的toFixed()方法保留指定的小数位数
  3. 幂和开根号
    • Javascript 没有提供幂计算、开根号的运算符。需要使用Math对象的相关方法进行计算。
    • Math.pow(2,3) 幂计算,2的3次方
    • Math.sqrt(81) 开根号运算符
    • 向上取整 Math.ceil()
    • 向下取整 Math.floor()

数据类型简介和检测

基本数据类型

  1. null 类型
    • 表示“空”,它是“空对象”
    • 当我们需要将对象销毁、数组销毁或者删除事件监听时,通常将它们设置为null
      • box.click = null
    • 使用 typeof 检测 null 值,结果是object,这点尤其要注意
    • 类型和typeof 检测结果并不是一一对应的,比如数组用typeof检测出来的结果也是object
  2. undefined 类型
    • 一个没有被复制的变量的默认值是undefined,而undefine的类型也是undefined
    • 即:undefined又是值,又是一种类型,这种类型只有它自己一个值
  3. 布尔类型 (Boolean)
    • 布尔型值只有两个:true 和 fasle,分别表示真和假
  4. 字符串类型(String)
    • 字符串要用引号包裹,双引号或者单引号均可
    • 加号可以用来拼接多个字符串
    • 空字符串,直接写闭合的引号即可
    • 字符串的 length 属性表示字符串的长度
    • 字符串的常用方法
      • charAt()
        • 得到指定位置字符
      • substring()
        • 提取子串
          • substring(a,b) 方法得到从 a 开始到b结束(不包含b处)的子串
          • 如果省略第二个参数,返回字符串一直到字符串的结尾
          • substring(a,b) 中,a 可以大于 b ,数字顺序将自动调整为小数在前
      • substr()
        • 提取子串
          • substr(a,b) 方法得到从 a 开始的 长度为b的子串
            • 子串的长度而不是编号
          • substr(a,b) 方法 b 参数可以省略,表示到文档的结尾
          • substr(a,b) 方法中,a可以是负数,表示倒数位置
      • slice()
        • 提取子串
          • slice(a,b) 方法得到从 a 开始到b结束(不包含b处)的子串
          • slice(a,b) 方法 a 参数可以是负数
          • slice(a,b) 方法 a 参数必须小于b
      • toUpperCase()
        • 将字符串变为大写
      • toLowerCase()
        • 将字符串变为小写
      • indexOf()
        • 检索字符串
          • 返回某个字符串值在首次出现的位置
          • 如果检测的字符串值没有出现,则返回-1
  5. 数字类型(Number)
    • 所有数字不分大小、不分整浮、不分正负、都是数字类型
    • 小数中,零是可以省略的
    • 较大数或较小数(绝对值比较小),可以写成科学计数法
      • 例:3e8、3e-4
    • 不同进制的数字
      • 二进制数值以0b开头 例:0b10
      • 八进制数值以0开头 例:017
      • 十六进制以0x开头 例如:0x156
    • 一个特殊的数字型值NaN
      • NaN是英语 “not a number” 的 意思,即“不是一个数”,但它是一个数字类型的值
      • typeof NaN // number
      • 0/0 的结果就是NaN,事实上,在数学运算中,若结果不能得到数字,其结果往往都是NaN
      • NaN有一个“奇怪”的性质,不自等。

数据类型的转换

  1. 其它值 -> 数值
    • Number() 系统内置的构造函数
    • parseInt() 函数
    • parseFloat() 函数
  2. 其它值 -> 字符串
    • String() 函数 系统内置的构造函数
    • toString() 方法,几乎所有的值都有该方法
    • 当数值直接调用 toString() 方法的时候,要加上括号 例:(5).toString()
  3. 其它值 -> 布尔值
    • Boolean() 函数

复杂数据类型简介

  1. 对象 Object
  2. 方法 Function
  3. 复杂数据类型都是“引用类型”

typeof 运算符可以检测值或者变量的类型

1
2
typeof 5; 
typeof "shanmu";
  1. typeof 不是内置函数 是操作符

输出语句

  1. alert
  2. console

前端开发主要有哪些层,语言和功能是什么?

  1. HTML
    • 结构层 搭建骨架、描述页面语义
  2. CSS
    • 样式层
  3. Javascript
    • 行为层 表单验证、数据交互、数据收发等

变量声明提升(面试题)

  1. 你可以提前使用一个稍后才声明的变量,而不会引发异常
  2. 在执行所有代码前,JS有预解析阶段,会预读所有变量的定义
  3. 只提升定义,并不提升值
  4. var 关键词可以变量提升, let 并不能
  5. 在实际开发中,一定要先定义变量赋值,再使用。

变量是什么

  1. 要定义变量,第一步就是声明它,并给它赋值
  2. 变量是计算机语言中能存储计算结果或能表示值抽象概念
  3. 变量不是数值本身,它们仅仅是一个用于存储数值的容器
  4. 标识符的命名规则(函数、类名、对象的属性也要遵守这个规则)
    • 变量名大小写敏感,a和A两个不同的变量
    • 不能是关键词或保留词
    • 只能由字母、数字、下划线、$组成,但不能以数字开头
  5. 优秀的变量命名法
    • 驼峰命名法 例如:mathTestScore
    • c风格 例如:math_test_score
    • 匈牙利命名法 例如:iMathTestScore ,第一个字母 i,提示变量类型
  6. 变量的默认值
    • 一个变量只定义,但没有赋值,默认是undefined
  7. 等号表示赋值
  8. 同时声明多个变量
    • var a=0,b=0;
  9. var 定义的变量会被挂载在 window 上,let 不会

函数的基本使用

  1. 函数的参数和返回值
    • 参数可多可少,用逗号分开
    • 函数体内可以使用 return 关键词表示 “函数的返回值”
    • 调用一个有返回值的函数,可以被当做一个普通纸,从而可以出现在哪任何可以书写值的地方
    • 调用函数时,一旦遇见 return 语句则会立即退出函数,将执行权还给调用者
  2. 函数的定义和调用
    • 和变量相似,函数必须先定义然后才能使用
    • 使用 function 关键词定义函数,function 是“功能”的意思
    • 函数名,必须符合JS标识符的命名规则
  3. 什么是函数
    • 函数就是语句的封装,可以让这些代码方便的被复用
    • 函数具有“一次定义,多次调用”的优点
    • 使用函数,可以简化代码,让代码更具有可读性
  4. 函数声明的提升(面试题)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    fun()
    // 函数表达式
    var fun = function () {
    console.log("A")
    }

    function fun() {
    console.log("B")
    }
    fun()

    // B A
    • 和变量声明提升类似,函数声明也可以被替身,函数表达式不能提升
    • 变量的提升,只提升定义,不提升值。
    • 函数优先提升,然后再提升变量。

函数算法题

  1. 函数算法题1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    /**
    * 【阿姆斯特朗数】 数字是 n 位数 , 该数字的每一位的 n 次方之和等于该数字本身
    * 阿姆斯特朗数是指上述条件成立的任意位数的数字 水仙花数是指上述条件成立的 3 位数
    */
    function factorial(n) {
    let result = 1
    for (let i = 1; i <= n; i++) {
    result *= i
    }
    return result
    }

    for (let i = 100; i <= 999; i++) {
    var str = i.toString();
    var a = Number(str[0]);
    var b = Number(str[1]);
    var c = Number(str[2]);

    if (factorial(a) + factorial(b) + factorial(c) == i) {
    console.log("i", i)
    }
    }
  2. 函数算法题2
    • 函数是JS的一等公民,它可以当做参数传入另一个函数
    • sort()函数 这个函数中的a,b分别表示数组中靠前和靠后的项,如果需要将它们交换位置,则返回任意整数,否则返回负数
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      var arr = [33, 22, 55, 11];
      arr.sort(function (a, b) {
      // if (a > b) {
      // return 1
      // } else {
      // return -1
      // }
      return b-a
      })
      console.log("arr", arr)

递归

  1. 什么是递归
    • 函数的内部语句可以调用这个函数自身,从而发起对函数的一次迭代,在新的迭代中,又会执行调用函数自身的语句,从而又产生一次迭代,当函数执行到某一次时,不在进行新的迭代,函数被一层一层返回,函数被递归。
    • 递归是一种较为高级的编程技巧,它把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
    • 递归的要素
      • 边界条件:确定递归到何时终止,也称为递归出口
      • 递归模式:大问题是如何分解为小问题的,也称为 递归体
  2. 递归常见算法题
    • 斐波那契数列
      1
      2
      3
      4
      function fib(n) {
      if (n == 0 || n == 1) return 1;
      return fib(n - 1) + fib(n - 2)
      }
    • 阶乘
      1
      2
      3
      4
      5
      6
      7
      function test(n) {
      console.log("n:",n)
      if (n == 1) return 1;
      console.log("123")
      return n * test(n - 1)
      }
      test(3)
  3. 实现深克隆
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var arr1 = [12, 34, 12, 45, [12, 44]];
    function deepClone(arr) {
    var result = [];
    for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
    result.push(deepClone(arr[i]))
    } else {
    result.push(arr[i])
    }
    }
    return result;
    }
    var arr2 = deepClone(arr1);

作用域和闭包

  1. 全局变量和局部变量
    • JavaScript 是 函数作用域编程语言:变量只在其定义时所在的function内部有意义。
    • 如果变量不定义在函数的内部,此时这个变量就是全局变量
    • 遮蔽效应
      • 如果函数中也定义了和全局同名的变量,则函数内的变量会将全局的变量 “遮蔽”
    • 形参也是局部变量
      1
      2
      3
      4
      5
      6
      7
      var a = 10;
      function fun(a) {
      a++
      console.log(a)
      }
      fun(7)
      console.log(a)
    • 函数的嵌套
      • 一个函数内部也可以定义一个函数。和局部变量类似,定义在一个函数内部的函数时局部函数
    • 不加 var 将定义全局变量
  2. 作用域链
    • 就是这个变量会被一层一层的(从内层到外层),去寻找它的作用域
  3. 闭包
    • 什么是闭包
      • Javascript 中函数会产生闭包(closure)。闭包是函数本身和该函数声明时所处的环境状态的组合。
      • 函数能够“记忆住”其定义时所处的环境,即使函数不在其定义的环境中被调用,也能访问定义时所处环境的变量。
    • 观察闭包现象
      • 在JavaScript中,每次创建函数时都会创建闭包。但是,闭包特性往往需要将函数“换一个地方”执行,才能观察出来
    • 闭包非常实用
      • 因为它允许我们将数组与操作改数组的函数关联起来,这与“面向对象编程”有少许相似之处
    • 闭包的功能
      • 记忆性
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        function createCheckTemp(standardTemp) {
        return function checkTemp(n) {
        if (n <= standardTemp) {
        alert('你的体温正常')
        } else {
        alert('你的体温偏高')
        }
        }
        }

        var area1 = createCheckTemp(37.1)
        var area2 = createCheckTemp(38.1)
        area1(38)
        area2(38)
        • 当闭包产生时,函数所处环境的状态会始终保持在内存中,不会在外层函数调用后被自动清除。这就是闭包的记忆性
      • 模拟私有变量
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        function fun() {
        var a = 1;
        return {
        getA: function () {
        return a
        },
        add: function () {
        return a++
        },
        pow: function () {
        return a *= 2
        }
        };
        }
        var obj = fun()
        obj.pow()
        obj.add()
        alert(obj.getA())
      • 使用闭包的注意点
        • 不能滥用闭包,否则会造成网页的性能问题,严重时可能导致内存泄漏。所谓内存泄漏是指程序中以动态分贝的内存由于某种原因未释放或无法释放
      • 闭包面试题
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        function addCount() {
        var count = 0;
        return function () {
        count = count + 1;
        console.log(count)
        }
        }
        var fun1 = addCount()
        var fun2 = addCount()
        fun1()
        fun2()
        fun2()
        fun1()

立即执行函数

  1. 立即执行函数 IIFE
  2. 立即调用函数,一旦被定义,就立即被调用
  3. 形成IIFE的方法
    1
    2
    3
    4
    5
    // 运行函数 
    +function fun1(){ alert('立即调用1'); }()
    -function fun2(){ alert('立即调用2'); }()
    ~function fun3(){ alert('立即调用3'); }()
    !function fun4(){ alert('立即调用4'); }()
    • 函数必须转为“函数表达式”才能被调用
  4. IIFE的作用
    • 为变量赋值
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      var age = 28;
      var sex = '女';
      var title = (function () {
      if (age < 18) {
      return '小朋友'
      } else {
      if (sex == '男') {
      return '先生'
      } else {
      return '女士'
      }
      }
      })()
      alert(title)
    • 将全局变量变为局部变量
      1
      2
      3
      4
      5
      6
      7
      8
      9
      var arr = []
      for (var i = 0; i < 5; i++) {
      (function (i) {
      arr.push(function () {
      alert(i)
      })
      })(i)
      }
      arr[1]()

DOM 基本概念

  1. DOM 是操控 HTML和CSS的桥梁
  2. DOM (Doucument Object Model) 文档对象类型,是Javascript操作HTML文档的接口,使文档操作变得非常优雅简便
  3. DOM最大的特点是将文档表示为节点树

节点访问和位置关系

  1. 访问元素节点
    • 访问元素节点的常用方法
      • document.getElementById()
        • 通过id得到元素
          • 如果页面上有相同id的元素,则只能得到一个
          • 不管元素藏得多深,都能把它找到
          • 延迟运行
            • 通常JS 一定要写到HTML的节点后面,否则JS无法找到相应的HTML节点
            • 可以使用 window.onload = function(){} 事件 ,使页面加载完后再执行指定代码
      • document.getElementsByTagName()
        • 通过标签名称得到元素数组
      • document.getElementsByClassName()
        • 通过类名得到元素数组
      • document.querySelector()
        • 通过选择器得到元素
      • document.querySelectorAll()
        • 通过选择器得到元素数组
  2. 节点的关系
    • 相对于父节点
      • 可以使用 farstChild 得到第一个子节点
      • 可以使用 lastChild 得到最后一个子节点
    • 相对于子节点
      • 父节点可以通过使用 childNodes 得到所有的子节点信息
      • 子节点可以通过 parentNode 来访问父节点
      • 对于后面一个 兄弟节点 可以使用 nextSibling 获取
      • 对于前面一个兄弟节点 可以使用 perviousSibling 获取前面一个
    • 注意:文本节点也属于节点
      • 文本节点也属于节点,使用节点关系时,一定要注意
    • 只考虑元素节点
      • children
      • firstElementChild
      • lastElementChild
      • perviousElementSibling
      • nextElementSiling

节点操作

  1. insertBefore
    • 父节点.insertBefore(孤儿节点,标杆节点);
  2. appendChild
    • 父节点.appendChild(内容)
    • 在尾部追加
  3. 改变元素节点的CSS样式
    • oBox.style.fontSize = '32px'
  4. 改变元素的HTML的属性
    • W3C 属性 直接,元素.属性 = 属性值
    • 非标准 W3C 属性
      • 元素.setAttribute(key,value)
      • 元素.getAttribute(key)

nodeType常用属性值

  • 1 元素节点,例如<p> 和 <div>
  • 3 文字节点
  • 8 注释节点
  • 9 document节点
  • 10 DTD节点

节点的创建、移除和克隆

  1. createElement
    • 创建一个指定tagname的HTML元素
  2. 获取body节点
    • document.body
  3. 获取html节点
    • document.documentElement
  4. 移动节点
    • 新父节点.appendChild(已经有父亲的节点)
    • 新父节点.insterBefore(已经有父亲的节点,标杆子节点)
  5. 删除节点
    • 父节点.removeChild(要删除的子节点)
    • 节点不能主动删除自己,必须由父节点删除它
  6. 克隆节点
    • cloneNode() 方法可以克隆节点,克隆出的节点是“孤儿节点”
    • var 孤儿节点 = 老节点.cloneNode(true|false);
    • cloneNode 参数是一个布尔值,表示是否采用深度克隆;如果为true该节点的所有后代节点也都会被克隆,如果为false,则只克隆该节点本身
  7. 访问元素节点
    • 所谓 ”访问“元素节点,就是指”得到“、”获取“页面上的元素节点。
    • 访问元素节点 主要依赖于 document

DOM事件

  1. 事件监听
    • 什么是“事件监听”
      • DOM允许我们书写Javascript代码以让HTML元素对事件做出反应
      • 什么是”事件”:用户与网页的交互动作
        • 点用户点击元素的时候
        • 点鼠标移动到元素的时候
        • 当网页加载完成的时候…
      • “监听”,顾名思义就是让计算机随时能够发现这个事件发生了,从而执行程序员预先编写的一些程序
      • 设置事件监听的方法主要有 onxxx 和 addEventListener()
    • 常见鼠标事件监听
      • onclick 当鼠标点击某个对象
      • ondblclick 当鼠标双击某个对象
      • onmousedown 当某个鼠标按键在某个对象上被按下
      • onmouseup 当某个鼠标按键在某个对象上被松开
      • onmousemove 当某个鼠标按键在某个对象上被移动
      • onmouseenter 当鼠标进入某个对象
      • onmouseleave 当鼠标离开某个对象
    • 常见的键盘事件监听
      • onkeyperss 当某个键盘的键被按下(系统按钮如箭头键和功能键无法得到识别)
      • onkeydown 当某个键盘的键被按下(系统按钮可以识别,并且会优先onkeypress发生)
      • onkeyup 当某个键盘的键被松开
    • 常见的表单事件监听
      • onchange 当用户改变域的内容
      • onfocus 当某个元素获得焦点(比如tab或鼠标点击)
      • onblur 当元素失去焦点
      • onsubmit 当表单被提交
      • onreset 当表单被重置
      • oninput 当用户输入
    • 常见的页面事件监听
      • onload 当页面或图像被完成加载
      • onunload 当用户退出页面
  2. 事件传播
    • 事件的传播是:先从外到内,然后再从内到外
      • 从外到内、捕获阶段(capturing phase)
      • 从内到外、冒泡阶段(Bubbling phase)
      • onxxx 这样的写法只能监听冒泡阶段
    • addEventListener() 方法
      • DOM 0级:只能监听冒泡阶段
        1
        2
        3
        box2.onclick = function(){
        console.log("我是box2")
        }
      • DOM 2级事件监听
        1
        2
        3
        box1.addEventListener('click',function(){

        },true)
        • true 监听捕获的阶段
        • false 监听冒泡阶段【默认】
      • 注意事项:最内部的元素不再区分捕获和冒泡阶段,会先执行写在前面的监听,然后执行后写的监听
      • 注意事项:如果给元素设置相同的两个或多个同名事件,则DOM0级写法后面写的会覆盖先写的;而DOM2级会按照顺序执行
  3. 事件对象
    • 什么是事件对象
      • 事件处理函数提供一个形式参数,它是一个对象,封装了本次事件的细节
    • e.charCode 和 e.keyCode 属性
      • e.charCode 属性通常用于 onkeypress 事件中,表示用户输入的字符的 “字符码”
        • 数字0 ~ 数字9 48 ~ 57
        • 大写字母A ~ Z 65 ~ 90
        • 小写字母 a ~ z 97 ~ 122
      • e.keyCode 属性通常用于 onkeydown 事件和onkeyup中,表示用户按下按键的 “键码”
        • 数字0 ~ 数字9 48 ~ 57
        • 字母部分大小写 a ~ z 65 ~ 90 (不区分大小写)
        • 四个方向键(左、上、右、下) 37、38、39、40
        • 回车键 13
        • 空格键 32
    • e.preventDefault() 方法
      • 阻止事件产生的“默认动作”
    • e.stopPropagation() 方法
      • 阻止事件继续传播
      • 在一些场合,非常有必要切断事件继续传播,否则会造成页面特效显示出bug
    • 鼠标滚轮事件
      • 鼠标滚轮事件是 onmousewheel ,它的事件对象e提供deltaY 属性 表示鼠标滚动方向,向下滚动时返回正值,向上滚动时,返回负值。
  4. 事件委托
    • 批量添加事件监听的性能问题
      • 每一个事件监听注册都会消耗一定的系统内存,而批量添加事件会导致监听数量太多,内存消耗会非常大
    • 定义
      • 利用事件冒泡机制,将后台元素事件委托给祖先元素
    • e.target 和 e.currentTarget 属性
      • target
        • 触发此事件的最早元素,即“事件源元素”
      • currentTarget
        • 事件处理程序附加到的元素
    • 使用场景
      • 当有大量类似元素需要批量添加事件监听时,使用事件委托可以减少内存开销
      • 当有动态元素节点上树时,使用事件委托可以让新上树的元素具有事件监听
    • 使用时注意事项
      • onmouseenter 和 onmouseover 都表示“鼠标进入”,它们有什么区别呢?
        • onmouseenter 不冒泡
        • onmouseover 冒泡
      • 不能委托不冒泡的事件给祖先元素
      • 最内层的元素不能再有额外的内层元素了,比如
        1
        2
        3
         <ul id="list">
        <li> <span>我是span</span>列表项</li>
        </ul>

BOM是什么

  1. 一些与浏览器改变尺寸,滚动条滚动的特效,都要借助BOM技术
  2. BOM(Browser Object Model, 浏览器对象模型) 是JS与浏览器窗口交互的接口

BOM常用对象

  1. Window 对象
    • window 对象是当前JS脚本运行所处的窗口,而这个窗口中包含DOM结构,window.document属性就是document对象
    • 在有标签页功能的浏览器中,每个标签都拥有自己的window 对象;也就是说,同一个窗口的标签页之间不会共享一个window对象
    • 全局变量是window变量的属性
      • var a = 1;window.a == a // true
    • 内置函数普遍是window的方法
      • 如setInterval、alert
      • window.alert ==alert // true
      • window.hasOwnProperty('alert') // true
  2. Navigator 对象
    • window.navgator 属性可以检索navigator对象,它内部含有用户此次活动的浏览器的相关属性和标识
      • appName 浏览器官方名称
      • appVersion 浏览器版本
      • userAgent 浏览器用户代理(含有内核信息和封装壳信息)
      • platform 用户操作系统
  3. History 对象
    • window.history 对象提供了操作浏览器会话历史的接口
    • 常用的操作就是模拟浏览器的回退按钮
    • history.back() history.go(-1)
  4. History 对象
    • window.location 标识当前所在网址,可以通过给这个属性赋值命令浏览器进行页面跳转
    • 重新加载当前页面
    • 可以调用location的reload方法以重新加载当前页面,参数true标识强制从服务器加载
    • GET请求查询参数
      • window.location.search 属性即为当前浏览器的GET请求查询参数
  5. 窗口尺寸相关属性
    • innerHeight
      • 浏览器窗口的内容区域的高度,包含水平滚动条(如果有的话)
    • innerWidth
      • 浏览器窗口的内容区域宽度,包含垂直滚动条(如果有的话)
    • outerHeight
      • 浏览器窗口的外部高度
    • outerWidth
      • 浏览器窗口的外部宽度
    • 获得不包含滚动条的窗口宽度,要用 document.documentElement.clientWidth
    • resize 事件
      • 在窗口大小改变以后,就会触发resize事件,可以使用window.onresize或者window.addEventListener(‘resize’) 来绑定事件处理函数
    • 已卷动高度
      • window.scrollY 属性表示在垂直方向已滚动的像素值
    • 已动高度
      • document.documentElement.scrollTop 属性也表示窗口卷动高度
      • document.documentElement.scrollTop 不是只读的,window.scrollY 属性是只读的
    • scroll事件
      • 在窗口被卷动之后,就会触发scroll事件,可以使用 window.onscroll 或者 window.addEventListener(‘scroll’) 来绑定事件处理函数
    • DOM元素都有offsetTop属性,表示此元素定位到祖先元素的垂直距离
      • 定位祖先元素:在祖先中,离自己最近的且拥有定位属性的元素

常用文本样式属性

  1. color
    • 设置文本内容的前景色
      • RGBA ,最后一个表示透明度,0表示纯透明,1表示纯实心
    • 16进制,RGB,RGBA
    • 如果颜色值是#aabbcc的形式,可以简写为#abc
      • #ff0000 -> #f00
  2. font-size
    • 设置字号,单位通常px
  3. font-weight
    • normal 正常粗细,与400等值
    • bold 加粗,与700等值
    • lighter 更细,大多数中文字体不支持
    • bolder 更粗,大多数中文字体不支持
  4. font-style
    • normal 取消倾斜,比如把天生倾斜的i、em等标签设置为不倾斜
    • italic 设置为倾斜字体(常用)
    • oblique 设置为倾斜字体(用常规字体模拟,不常用)
  5. text-decoration
    • none 没有修饰线
    • underline 下划线
    • line-through 删除线

继承性

  1. color
  2. font-开头的
  3. list-开头的
  4. text-开头的
  5. line-开头的
  6. 因为文字相关属性有继承性,所以通常会设置body标签的字号、颜色、行高等,这样就能当做整个网页的默认样式了
  7. 在继承的情况下,选择器权重计算失效,而是“就近原则”,继承的不如元素选中的权重大

字体属性详解

  1. font-family
    • 字体可以是列表形式,一般英语字体放前面,后面的字体是前面字体的“后备”字体
    • font-family: serif, “Times New Roman”, “微软雅黑”;
    • 字体名称中有空格,必须用引号包裹
    • 中文字体可以称呼它们的英语名字
      • “Microsoft Yahei” 等同于 “微软雅黑”
      • “SimSun” 等价于 “宋体”
    • 字体通常必须是用户计算机中已经安装好的字体
    • 定义新字体,需要我们有新字体 @font-face

段落和行相关属性

  1. text-indent 属性
    • 定义文本内容首行缩进量
  2. line-height
    • 定义行高
    • line-height:30px
    • line-height:1.5 字号的倍数
    • line-height:150% 字号的倍数
  3. 单行文本垂直居中
    • 行高=盒子高度,即可实现单行文本的垂直居中
  4. text-align:center
    • 文字水平居中
  5. font 合写属性
    • font: italic bold 20px/1.5 “阿里妈妈刀隶体 Regular”;
0%