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 不会返回,函数会继续执行
用
every
和some
替代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
反而不会报错暂时性死区的本质就是,只要一进入当前作用域,所使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量