杂碎知识点
-
快照 英文名称为snapshot,即将某个时刻内存中的数据备份成文件。
-
SVG 是一种基于XML的矢量图形格式,用于在Web或其它环境中显示图形,允许编写可伸缩的二维图形,也通过层叠样式表(CSS)或JavaScript进行操作。
SVG能够响应当前Web开发对图形可伸缩性、响应性、交互性、可编程性、性能和可访问性的要求。
如何绘制SVG图形 -
SPDY协议 意为speedy,即会话层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。SPDY并不是用于替代HTTP的协议,而是对于HTTP协议的增强。
-
js中的valueOf方法
对象 操作 默认 返回“[object class]”,其中class是对象类型的名称,值为"Object"、“String”、“Number”、“Function”、"Document"等 Array 将Array中的元素转换为字符串,结果字符串中由逗号分隔,且相互连接 Boolean 若Boolean为true,则返回"true",否则返回“false” Date 返回日期的文字表示法 Error 返回一个包含相关错误信息的字符串 Function 返回如下格式的字符串,其中functionname是被调用toString方法函数的名称:function functionname(){[native code]} RegExp 返回正则表达式直接量的字符串 Number 返回数字的文字表示 String 返回String对象的值 返回的是一个字符串
若对象存在任意原始值,则默认将对象转化为它的原始值,若对象是复合值,则大多数对象无法真正为一个原始值。
-
js函数内部修改外部传入的变量
function setN(obj){ obj.name = 'aaa' obj = new Object() obj.name = 'bbb' } var per = new Object() setN(per) alert(per.name) /* 结果为aaa 因为仅仅只是传入了地址,函数拿到地址修改其中的变量值,之后重新使用new Object()时即重新制定了新的地址,因此与外部参数无关 */
var a = {n:1} var b = a a.x = a = {n:2} console.log(a.x) console.log(a) console.log(b) console.log(b.x) /** * undefined * { n: 2 } 地址被改变的问题 * { n: 1, x: { n: 2 } } b还是引用的原来的地址 * { n: 2 } */ // . 的优先级高于 = ,因此a.x = a = {n:2}中,a.x先执行,假设原有的a地址为000011,则此时的情况即为[000011].x,而b即获取了000011地址的内容。 // 之后等式从右到左进行赋值,此处的a获得了另外一个地址000022,因此另外的地址获取到了n:2,但a本身不存在x属性,因此 a.x = {n:3} console.log(a.x) //{n:3}
-
map函数 将调用的数组的每个元素传递给指定的函数,并返回一个数组,它包含该函数的返回值。传递给map()的函数应该有返回值。map()返回的是新数组,不修改被调用的数组,但是结构与被调用的数组相同,若调用稀疏数组,则返回的也是相同格式的稀疏数组:具有相同的长度,相同的缺失元素。
// 为数组arr中的每个元素求二次方,不要直接修改数组arr,结果返回新的数组 function square(arr){ return arr.map(function(item){ return item*item }) } var arr = [1,2,3,4]; console.log(square(arr)) // [ 1, 4, 9, 16 ]
-
字面量 固定的值,字面为什么含义就表示什么含义,可以参考此内容
-
Object.defineProperty Vue2的响应式机制就是用这个写的
一般可以为对象obj添加名为name的属性值为alice,如以下代码
let obj = {} Object.defineProperty(obj,'name',{ value:'alice' })
其中所定义的value值一般是不可修改的,若使用该方法修改将报错“不能重复定义”,使用obj.name方法不报错但实际上不会修改其中的值。
该方法的第三个参数其实是一个描述器,可以用于存储数据描述符以及存取描述符,如以下:
-
configurable 表示可配置的,默认false,当为true时,该属性的描述符才能被改变,同时该属性也能在对应的对象中删除
-
enumerable 表示可枚举的,默认false,当为true时,该属性将在枚举时枚举到除了configurable以及enumerable之外的所有可选键值
-
value 表示属性对应的值,默认undefined
-
writable 表示可写的,默认false,因此属性值不能修改,当为true时,属性值才能被赋值运算符更改成功
-
get
let obj = {} Object.defineProperty(obj,'name',{ configurable: true, enumerable: true, get: function(){ console.log('aaa') return 'tom' } }) console.log(obj.name) /** *aaa *tom *返回的tom即为get的返回值,若没有返回值则默认为undefined,get无需传入参数,但是里头的this指向一般是该对象,但不一定是 */
-
set
let obj = {} Object.defineProperty(obj,'name',{ configurable: true, enumerable: true, set: function(val){ console.log(`设置obj.name的值为${val}`)//此处是模板字面量 } }) obj.name = 'aaa' console.log(obj.name) /** * 设置obj.name的值为aaa * undefined */
-
-
创建带配置属性的对象方法可如下:
var person = { name: 'lifuya', age: 22, } var user = Object.create(person,{ height:{ value: 173, writable: true, enumberable: true, configurable: false, }, weight:{ value: 73, writable: true, enumberable: false, configurable: false, } }) // Object.getOwnPropertyNames()会遍历出自身的所有属性 for(let i in user){ console.log('first:',i) } console.log('second:',Object.keys(user)) console.log('third:',Object.getOwnPropertyNames(user)) /** * first: name * first: age * second: [] * third: [ 'height', 'weight' ] */
-
在提到ECMAScript规范时,经常会引用符号在规范中的名称,前缀为@@。比如,@@iterator指的就是Symbol.iterator
-
JS中的prototype、__proto__以及constructor
- ES6以前为了实现面对对象编程,使用函数function来代替class,即使用function来创建对象
function Puppy(){} // 可以直接使用new关键字生成实例: const myPuppy = new Puppy();
- 函数的本身即是构造函数,只需要使得上诉函数可以接受参数即可实现,因此
function Puppy(age){ this.puppyAge = age // 作为类使用的函数里面this总是指向实例化对象,即接下来所实例化的myPuppy,设计的目的即是让使用者可以通过构造函数给实例对象设置属性 } // 实例化时传入参数 const myPuppy = new Puppy(2) console.log(myPuppy.puppyAge) // 输出是2
- 实例方法使用prototype,js中要实现实例中的函数,则将该方法添加一个prototype属性,挂载在这上面的方法,在实例化时会给到实例对象,使用new关键字产生的实例都有类prototype上的属性和方法
Puppy.prototype.say = function(){ console.log("汪汪汪") } const myPuppy = new Puppy(2) myPuppy.say() // 此时即可调用该方法并输出汪汪汪
- 实例方法查找使用_proto_,实例所调用的方法来自于原型链上,如上诉例子,当你访问的一个对象myPuppy上没有的属性say时,对象会去__proto__上查找,__proto__的值等于父类的prototype,即myPuppy.__proto__指向了Puppy.prototype。若访问的属性在Puppy.prototype也不存在,则会继续往Puppy.prototype.__proto__上找,即在Object.prototype上找,在往上找即是null,这就是原型链
myPuppy.__proto__ == Puppy.prototype // true
-
静态方法 将其作为类函数的一个属性即可
Puppy.staticFunc = function(){ // staticFunc 即为一个静态方法 console.log('静态方法,this拿不到实例对象') } Puppy.staticFunc() // 需要通过类名类调用
静态方法一般用于与实例无关的操作,例如jQuery中的 ( s e l e c t o r ) 拿 到 的 就 是 实 例 对 象 , 使 用 (selector)拿到的就是实例对象,使用 (selector)拿到的就是实例对象,使用(selector).append()即是对实例对象执行append方法,其中的this指向实例;使用 . a j a x , 其 中 的 a j a x 与 D O M 实 例 没 有 关 系 , 不 需 要 t h i s , 可 以 直 接 挂 载 在 .ajax,其中的ajax与DOM实例没有关系,不需要this,可以直接挂载在 .ajax,其中的ajax与DOM实例没有关系,不需要this,可以直接挂载在上作为静态方法
-
继承 即子类能够继承父类的属性和方法,使用js的语言来说就是子类能够找到父类的prototype,最简单的方法就是子类原型的__proto__指向父类原型即可,但这种方式只能让子类访问到父类的原型链,但并不能执行父类的构造函数,因此还需要将子类使用new执行下父类的构造函数,但这种方法会多一个__proto__层级,可以修改为Child.prototype指向来解决,但后续需要将child.prototype.constructor重置回来
function parent(){ this.age = 25 } function child(){} child.prototype = new parent() // 修改子类原型的指向 child.prototype.constructor = child // 重置constructor const obj = new child() console.log(obj.age) // 25
-
typeof 一般用于判断一个变量的类型,但无法判断object的类型,如以下情况不可判断:
let s = new String() console.log(typeof s) // object
js底层存储变量时,会在变量的机器码的低位1-3位存储类型信息,例如:
- 000:对象
- 010:浮点数
- 100:字符串
- 110:布尔
- 1:整数
- null:所有的机器码都为0
- undefined:使用 -2^30 整数表示
因此,由于null的所有机器码都为0(即地位1-3的位置也都为0),typeof判断null时会将其当作对象看待
-
可以利用Object.prototype.toString来对一个变量的类型进行比较准确的判断
console.log(Object.prototype.toString.call(1)) console.log(Object.prototype.toString.call('hi')) console.log(Object.prototype.toString.call({a:'hi'})) console.log(Object.prototype.toString.call([1,'a'])) console.log(Object.prototype.toString.call(true)) console.log(Object.prototype.toString.call(()=>{})) console.log(Object.prototype.toString.call(null)) console.log(Object.prototype.toString.call(undefined)) console.log(Object.prototype.toString.call(Symbol(1))) /** * [object Number] * [object String] * [object Object] * [object Array] * [object Boolean] * [object Function] * [object Null] * [object Undefined] * [object Symbol] */
-
instanceof 主要作用是判断一个实例是否属于某种类型
let person = function(){} let man = new person() console.log(man typeof person) // Uncaught SyntaxError: missing ) after argument list console.log(man instanceof person) // true
也可以使用其来判断一个实例是否是其父类型或者祖先类型的实例
let person = function(){} let programmer = function(){} programmer.prototype = new person() programmer.prototype.constructor = programmer let man = new programmer() console.log(man instanceof programmer) //true console.log(man instanceof person) //true // 其中较为有趣的几个例子如下: console.log(Object instanceof Object) //true console.log(Function instanceof Function) //true console.log(Function instanceof Object) //true console.log(person instanceof person) //false console.log(person instanceof Object) //true console.log(person instanceof Function) //true
主要原理即右侧变量的prototype在左侧变量的原型链上即可,因此instanceof在查找的过程中会遍历左侧变量的原型链,直到找到右侧变量的prototype,若查找失败,则返回false
每个JavaScript对象都有一个隐式的__proto__原型属性,而显示的原型属性是prototype,只有Object.prototype.__proto__属性在未修改的情况下为null值。
-
yield 使生成器函数执行暂停,关键字后面的表达式的值返回给生成器的调用者,使一个基于生成器的版本的return关键字,实际例子
-
//创建对象时简写属性名称
//ES5
const message = {text:text} //将属性text赋值给text变量
//ES6
const message = {text} //将属性text分配给名为text的变量
-
使生成器函数执行暂停,关键字后面的表达式的值返回给生成器的调用者,使一个基于生成器的版本的return关键字,[实际例子](https://juejin.cn/post/6999530125020626957)
- [**for-in for-of 的区别**](https://juejin.cn/post/6916058482231754765)
- ```js
//创建对象时简写属性名称
//ES5
const message = {text:text} //将属性text赋值给text变量
//ES6
const message = {text} //将属性text分配给名为text的变量