知识需要积累。

打开有道云笔记,在前端目录中已经有约30多篇来自工作中,项目中或者书本中的知识点总结,大概看了一些,大部分都是JavaScript相关的知识点,css不多,这里筛选出一些来,按照时间顺序汇总分享出来。文章没有具体内容,也没有章节顺序,仅仅是一些知识点的碎片或者理论化的论点。时间跨度较长,可能有些知识已经过时或者本身总结过程中有错误或遗漏,请指正。

CSS

position 定位

static
  • 正常布局行为,即元素在文档流中当前的布局位置
  • top/right/left/bottom/z-index值在static定位元素下无效
relative
  • 会为元素预留空间。元素先放置在未添加定位时的位置,在不改变页面布局的前提下调整元素位置
  • table-*元素无效
absolute
  • 不为元素预留空间。指定元素相对于最近的非static定位的父级元素偏移
  • 绝对定位的元素可以设置外边距(margin),且不会与其他边距合并
fixed
  • 不为元素预留空间。指定元素相对于视窗viewport来定位元素的位置
  • 元素的位置在屏幕滚动时不会改变
  • fixed属性会创建新的层叠上下文
  • 当元素祖先的transform属性非none时,容器就会相对于该祖先(不是viewport)来定位
sticky (2018/03/18 补)
  • 盒元素根据正常流计算,然后相对于该元素在流中的flow root(BFC)和最近的块级祖先元素定位
  • 对table同relative
  • 当元素被sticky定位时,后续元素的位置扔按照该元素未定位时的位置来确定

JavaScript

作用域和函数作用域

作用域是一套用来确定如何查找变量对象的规则。

  • 如果查找的目的是给变量赋值,则会使用 LHS 查询
  • 如果查找的目的是获取变量的值,则会使用 RHS 查询
    • 赋值操作会导致LHS查询,= 操作符或调用函数时传入参数的操作都会导致关联作用域的赋值操作
    • LHSRHS都会从当前作用域开始一级一级作用域的查找,直到找到或者达到作用域的顶层

函数作用域的含义是指属于这个函数的全部变量都可以在整个函数的范围内使用及复用

  • 函数申明和函数表达式之间最重要的区别是函数的名称标识符将会被绑定在何处
//1.申明
function foo() {} //可以直接调用foo()
//2.表达式
var bar = function barfunc() {} //不可以直接调用barfunc()
//3.自执行函数
(function func(){
    ...
})() //func被隐藏
  • 申明提升:包括变量和函数在内的所有申明都会在任何代码被执行前首先被处理。
    • 定义申明是在编译阶段进行的
    • 赋值申明是在执行阶段进行的
    • 函数申明和变量申明都会被提升
      • 函数的申明优先于变量(包括表达式)
      • 变量申明,如果名称已存在则跳过该申明(防止覆盖同名函数申明)
      • 函数申明,如果名称已存在则被新函数的引用覆盖

闭包

当函数能够记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行的。

  • 闭包会阻止垃圾回收机制对其所在作用域的回收
  • 闭包可以让函数可以继续访问定义时的词法作用域,并一直保持着对其的引用

几个实现浅拷贝的方法

//数据源
const array = [1, 2, 3, {a : 1, b : 2}, true, [1,2,3]]
const object = {a : 1, b : 'string', c : function () {}, d : [1,2,3], f : true}
  • Object.assign()
//eg
Object.assign([], array)
Object.assign({}, object)
  • Array.prototype.slice (仅针对数组)
var arrClone = array.slice(0)
  • for ... in 循环

  • 扩展运算符 (2017年新增)

let arrClone = [...array]
let objClone = {...object}

原型

  • 每个函数都有一个prototype属性,该属性指向一个对象,即原型对象
  • 普通对象如 var a = {} 没有prototype属性
  • 每个对象都有一个__proto__属性,该属性指向其构造函数的原型对象,通过这个属性,让实例对象也能够访问原型上的方法。
  • 构造函数的prototype与所有实例对象的__proto__都指向原型对象,而原型对象的constructor指向构造函数
  • 通过字面量创建的对象都链接到Object.prototype上,即Object的原型对象上
  • delete关键字只能删除自身属性/方法,不能删除原型链上的属性/方法
  • 不能使用delete来删除supper上的属性(2017年新增)

使用不同的方法来创建对象和生成原型链

  • 语法结构对象
    • 普通对象继承 Object.prototype的属性
    • 数组对象继承 Array.prototype的属性
    • 函数对象继承 Function.prototype的属性
    • ...
  • 构造器创建的对象(new 操作符)
  • Object.create创建的对象
    • Object.create用来创建一个新对象,新对象的原型对象就是调用该方法传入的第一个参数
  • 尽量减少原型链上的查找
  • hasOwnProperty是唯一处理属性且不会遍历原型链的方法。可以使用hasOwnProperty来检查自身属性

如何确定this的指向

  • this 的指向,是在函数被调用的时候确定的
  • 在函数执行过程中,this 一旦被确定,就不可更改了
  • 在一个函数上下文中,this 由调用者提供,由调用函数的方式来决定。
    • 如果调用者函数,被某一个对象所拥有,那么该函数在调用时,内部的this 指向该对象。
    • 如果函数独立调用,那么该函数内部的this ,则指向undefined。但是在非严格模式中,当this 指向undefined时,它会被自动指向全局对象。
  • 找到函数的调用者以及区分函数是否是独立调用就可以区分this

new 关键字

new 关键字让构造函数具有了与普通函数不同的许多特点。

  • 声明了一个中间对象(即实例对象)
  • 将实例对象的原型指向构造函数的原型
  • 将构造函数的this,指向实例对象
  • 返回实例对象
// new 关键字的内部模拟实现
function New (constructor) {
  //声明一个中间对象,即实例对象
  var instance = {}
  if (constructor.prototype !== null) {
    //将实例的原型指向构造函数的原型
    instance.__proto__ = constructor.prototype
  }
  //res为构造函数的执行结果,通过apply将构造函数内部的this修改为当前的instance实例对象。
  var res = constructor.apply(instance, Array.prototype.slice.call(arguments, 1))
  //当构造函数中明确指定了返回对象时,那么new的执行结果就是该返回对象
  if (res !== null && (typeof res === 'object' || typeof res === 'function')) {
    return res 
  }
  // 否则返回当前的实例对象
  return instance 
}

JSON.stringify的第二个参数

JSON.stringify接收3个参数,第二个参数一般容易被忽略,参数二主要有以下3中用法

  • 如果是函数,则对象在序列化过程,每个值的每个属性都会经过该函数处理。该函数接收key, value两个参数
    • 如果返回一个 Number, 转换成相应的字符串被添加入JSON字符串
    • 如果返回一个 String,该字符串被作为属性值加入JSON字符串
    • 如果返回一个 Boolean, "true" 或者 "false"被作为属性值被添加入JSON字符串。
    • 如果返回任何其他对象,该对象递归地序列化成JSON字符串,对每个属性调用replacer方法。除非该对象是一个函数,这种情况将不会被序列化成JSON字符串。
    • 如果返回undefined,该属性值不会在JSON字符串中输出(对数组无效,将会转换为 null)。
  • 如果是数组,则只有包含在这个数组中的属性值才会被序列化
  • 如果是null/未提供,则所有属性都会被序列化

call 要比 apply 快

call 和 apply 在运行时都会创建一个叫做argList的对象序列。call只需要将参数一一放在这个序列中,而apply的参数是数组,则需要获得其中的每一个值再放入

柯里化

柯里化是指这样一个函数:它接受函数A作为参数,运行后能够返回一个新的函数B,并且B能够处理A剩余的参数

柯里化通用表达式
var currying = function(fn) {
  var args = [].slice.call(arguments, 1);
  return function() {
    // 主要还是收集所有需要的参数到一个数组中,便于统一计算
    var _args = args.concat([].slice.call(arguments));
    return fn.apply(null, _args);
  }
}
柯里化特征
  • 接收单一参数,讲更多的参数通过回调函数来搞定
  • 返回一个新函数,用于处理所有想传入的参数
  • 利用call/apply/arguments对象来收集参数
  • 返回的这个函数正式用来处理收集起来的参数

-- EOF --

本文标题:这几年记在有道云笔记上的前端知识

本文链接:https://smohan.net/blog/jc6gyl

本站使用「 署名-非商业性使用 4.0 国际 (CC BY-NC 4.0) 」创作共享协议,转载或使用请署名并注明出处。 相关说明 »

更多文章

评论 「 ... 」