本两周学习总结

HTML attribute和DOM property

https://github.com/justjavac/the-front-end-knowledge-you-may-not-know/blob/master/archives/015-dom-attributes-and-properties.md

HTML attribute DOM property
值永远是字符串或 null 值可以是任意合法 js 类型
大小写不敏感 大小写敏感
不存在时返回 null 不存在时返回 undefined
对于 href, 返回 html 设置的值 对于 href 返回解析后的完整 url
更新 value, 属性也更新 更新 value, 特性不更新

DOM 属性

当浏览器解析玩HTML后,生成的DOM是一个继承自Object的常规Javascript,因此我们可以像操作任何js对象那样来操作DOM对象,也可以添加方法,你可以给每个html元素都添加属性或者方法

const el = document.getElementById('name')
el.foo = 'bar'
el.user = { name: 'jjc', age: '18'}

html 特性

html 也可以添加非标准属性
<input id="name" value="justjavac" foo="bar" />

当HTML特性映射为DOM属性时,只映射标准属性,访问非标准属性将得到undefined

const el = document.getElementById('name')
el.foo === undefined

好在DOM对象也提供了操作特性的API

  • Element.hasAttribute(name) – 判断某个特性是否存在
  • elem.getAttribute(name) – 获取指定特性的值
  • elem.setAttribute(name, value) – 设置指定特性的值
  • elem.removeAttribute(name) – 移除指定特性

根据 HTML 规范,标签以及特性名是不区分大小写的,因此以下代码是一样的

el.getAttribute('id')
el.getAttribute('ID')
el.getAttribute('iD')

并且,特性永远都是字符串或 null,如果我们为特性设置非字符串的值,则引擎会将此值转换为字符串

el.getAttribute('checked') === '' // 特性是字符串
el.checked === false              // 属性是 boolean 类型的值

el.getAttribute('style') === 'color:blue' // 特性是字符串
typeof el.style === 'object'                 // 属性是 CSSStyleDeclaration 对象

JavaScript30

https://soyaine.github.io/JavaScript30/

前端周刊

https://frontend-weekly.com/2019/phase-42.html

Reflect.ownKeys()与Object.keys()区别

Object.keys()返回属性key,但不包括不可枚举的属性

Reflect.ownKeys()返回所有属性key

查询资料:

Object.keys()

  • 相当于返回属性数组

Reflect.ownKeys()

  • 相当于Object.getOwnPropertyNames(target) 和 Object.getOwnPropertySymbols(target)

注意

getOwnPropertyNames() 返回所有属性的数组

Object.getOwnPropertySymbols() 返回所有符号属性直接发现在给定的对象

arguments 转数组的方法

function add(a,b){
  // return Array.prototype.slice.call(arguments)
  // return Array.from(arguments)
  // return [...arguments]
  return Array.prototype.concat.apply([],arguments)
}

forEach中return有效果吗?

在forEach中用return 不会返回,函数会继续执行

everysome替代forEach函数

  • every在碰到return false 的时候,中止循环
  • some在碰到return true 的时候,中止循环

isString

const getTag = val => Object.prototype.toString.call(val);
const isString=val=>{
  const type=typeof val;
  //如果是 new String('xxx') 又因为 type null等于'object'
  return type === 'string' || type === 'object' && val != null && !Array.isArray(val) && getTag(val) == '[object String]';
};

lodash 源码分析

https://github.com/L-WJ1995/Lodash_realize/blob/master/lodash.js

rambda

https://github.com/selfrefactor/rambda

发现一个好东西

https://lhammer.cn/You-need-to-know-css/#/zh-cn/

Element 的所有属性

https://developer.mozilla.org/zh-CN/docs/Web/API/Element

EventTarget

https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget

Promise

const isGreater = (a, b) => new Promise((resolve, reject) => {
  if (a > b) {
    result(true)
  } else {
    reject(false)
  }
});
isGreater(1, 2).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
});

伪类和伪元素的区别

CSS 伪类是添加到选择器的关键字,指定要选择的元素的特殊状态,:hover :visited

也有常见的伪类选择期 :nth-child :last-child

::伪元素

::before ::after CSS3 标准

:before CSS2 非标准

自己实现一个IndexOf

const strStr = (haystack, needle) => {
  if (needle === '') return 0;
  if (needle.length > haystack.length) return -1;
  if (needle.length === haystack.length && needle !== haystack) return -1;
  let i = 0, j = 0;
  while (i < haystack.length && j < needle.length) {
    // 同位相等,继续判断下一位
    if (haystack[i] === needle[j]) {
      i++;
      j++
    } else {
      i = i - j + 1; //i 偏移
      j = 0; //j 重置
      if (i + needle.length > haystack.length) { //如果偏移值+比较的和,大于目标值
        return -1
      }
    }
  }
  // 子串比完了,此时j应该等于needle.length
  if (j >= needle.length) {
    return i - needle.length
  } else {
    return -1
  }
};
console.log(strStr('abc', 'b'));

this

this 是一个对象

function Dog(name, age) {
  this.name = name;
  this.age = age;
  console.log(this);
}
// 直接调用
Dog('xxx', 'yyy'); // window
// new的方式调用
let a = new Dog('xxx', 'yyy');
console.log(a); // Dog { name: 'xxx', age: 'yyy' }

this指向问题

对象调用,this指向该对象

直接调用的函数,this指向全局window

通过new 的方式,this永远绑定在新创建的对象上

改变this指向

函数.call(对象,1,2,3...参数)

函数.apply(对象,[参数1,参数2,...])

发现一些有趣的项目

https://juejin.im/post/5dcc0546f265da79482566cb

Map key值取对象的注意点

let a = {a: 1};
let my1Map = new Map([[a, 1], ['b', 2]]);
console.log(my1Map.get(a)); //1
console.log(my1Map.get({a: 1}));// 这样是找不到的 undefined
console.log(my1Map); // Map { { a: 1 } => 1, 'b' => 2 }

reduce 制作实用函数

some

const some = (array, fn) => array.reduce((acc, val, index) => acc || fn(val, index), false);
console.log(some([1, 2, 3, 4], val => 6 === val)); // false
console.log(some([1, 2, 3, 4], val => 3 === val)); // true

all

const all = (array, fn) => array.reduce((acc, val) => acc && fn(val), true);
console.log(all([1, 1, 1, 1],val=>val===1));//true
console.log(all([1, 1, 1, 2],val=>val===1));//false

none

如果每一项都是返回false,none返回true,否则返回false

const none = (array, fn) => array.reduce((acc, val) => acc && !fn(val), true);
console.log(none([2,4,6,8], val => val % 2 == 1));  // true

map

const map=(array,fn)=>array.reduce((acc,val)=>acc.concat(fn(val)),[]);
const map=(array,fn)=>array.reduce((acc,val)=>(acc.push(fn(val)),acc),[]);

console.log(map([1, 2, 3, 4, 5], val => val * 4));

filter

const filter = (array, fn) => array.reduce((acc, val) => (fn(val) && acc.push(val), acc), []);


const filter = (array, fn) => array.reduce((acc, val) => fn(val) ? acc.concat(val) : acc, []);
console.log(filter([1, 2, 3, 4, 5], val => val % 2 == 0)); //[ 2, 4 ]

find

const find = (array, fn) => array.reduce((acc, val) => fn(val) ? val : acc);
console.log(find([1, 2, 3, 4], val => val == 2)); // 2

pipe

从左到右进行函数组合

const pipe = (array, init) => array.reduce((acc, val) => val(acc), init);
let a = pipe([val => val + 3, val => val + 4], 2);
console.log(a);// 9

zip

const zip = (list1, list2, arr = Array.from({length: Math.min(list1.length, list2.length)}, val => [])) => {
  return arr.reduce((acc, val, index) => (acc[index].push(list1[index], list2[index]), acc), arr);
};
console.log(zip([1, 2, 3], [3, 4]));
// [ [ 1, 3 ], [ 2, 4 ] ]

includes

const includes = (array, target) => array.reduce((acc, val) => acc || val == target, false);
console.log(includes([1, 2, 3, 4, 5], 5));//true

compace

从列表中删除假值

const compact = (list) => list.reduce((acc, val) => (val && acc.push(val), acc), []);
console.log(compact([1, 2, null, false, '', 3, 5])); //[ 1, 2, 3, 5 ]

多选框默认颜色及选中颜色的问题

<select class="form-control yl_height_select" ng-model="params.attackType"
      ng-class=" {yl_css_select:!params.attackType}">
                                    <option value="" style="display: none;" disabled selected>请选择攻击类型</option>
                                    <option ng-repeat="item in attackTypeOpts" value="{{item.value}}">{{item.label}}
                                    </option>
                                </select>
当params.attackType没有值的时候展示 yl_css_select

typeof 的安全问题

typeof x; //报错
let x;

"暂时性死区",就是变量x使用let 命令生命,在生命之前,都属性x的"死区",只要用这个变量就会报错

typeof  x //undefined

但是,如果变量没有被声明,使用typeof 反而不会报错

暂时性死区的本质就是,只要一进入当前作用域,所使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量

posted @ 2019-11-20 10:14  猫神甜辣酱  阅读(285)  评论(0编辑  收藏  举报