你盼世界,我盼望你无bug
。Hello 你们好!我是霖呆呆!前端
从这周起呆呆每周都会分享七道前端题给你们,系列名称就是「DD每周七题」。git
系列的形式主要是:3道JavaScript
+ 2道HTML
+ 2道CSS
,帮助咱们你们一块儿巩固前端基础。github
全部题目也都会整合至 LinDaiDai/niubility-coding-js 的issues
中,欢迎你们提供更好的解题思路,谢谢你们😁。web
console.log(Array(3))
console.log(Array(3, 4)) console.log(new Array(3)) console.log(new Array(3, 4)) console.log(Array.of(3)) console.log(Array.of(3, 4)) 复制代码
「考察知识点:」数组
Array()
和
new Array()
Array()
参数个数不一样时的不一样表现
Array.of()
的做用
「结果:」浏览器
console.log(Array(3)) // [empty x 3]
console.log(Array(3, 4)) // [3, 4] console.log(new Array(3)) // [empty x 3] console.log(new Array(3, 4)) // [3, 4] console.log(Array.of(3)) // [3] console.log(Array.of(3, 4)) // [3, 4] 复制代码
「总结:」编辑器
Array
使不使用
new
效果都是同样的
Array
方法,若是参数是一位的话,这个参数表示的是数组的长度,并建立此长度的空数组
Array
方法,若是参数是多位的话则每个参数都是数组的一项,会按顺序返回数组
Array.of()
接收任意个参数,将按顺序成为返回数组中的元素,并返回这个新数组。
// cool点的写法:
[...Array(100).keys()] // 其余方法: Array(100).join(",").split(",").map((v, i) => i) Array(100).fill().map((v, i) => i) 复制代码
后面两种方法相信你们都能看到懂,也没啥好说的了😄,让咱们仔细看一下这个比较cool
的写法:ui
使用Array(100)
建立一个内容全为empty
的数组:[empty x 100]
this
使用keys()
方法从数组建立一个包含数组键的可迭代对象:
可迭代对象是否是让你想到了generator
,没错的,这里的keys()
是Array.prototype
上的方法,你们可能会把它和咱们以前用的比较多的Object.keys()
搞混。
说一下它的做用吧,它其实就像刚刚介绍的同样,会建立一个可迭代对象,那么小伙伴们应该知道,一个可迭代对象返回的数据会是这样的:
{ value: 0, done: false }
复制代码
value
为此次的返回值,done
为当前可迭代对象的逻辑块是否执行完成。
因此你会看到如下这段代码是会这样执行的:
let it = Array(100).keys()
console.log(it.next) // {value: 0, done: false} console.log(it.next) // {value: 1, done: false} console.log(it.next) // {value: 2, done: false} console.log(it.next) // {value: 3, done: false} 复制代码
至于[...arr]
这个就是ES6
的写法了,转化为数组,固然你也能够直接用Array.from()
。这两种方式都支持将「可迭代对象」转换为数组。
这道题的意思是:提供一个createArr()
方法,用此方法建立的数组知足arr[-1] = arr[arr.length - 1]
:
function createArr (...elements) {
// ...代码 return arr } var arr1 = createArr(1, 2, 3) console.log(arr1[-1]) // 3 console.log(arr1[-2]) // 2 复制代码
「解题思路:」
其实对于这类题目,我首先想到的会是Object.defineProperty()
或者Proxy
。由于这里涉及到了对数组值的获取,显然用Proxy
是比较合适的。什么?你问我为何不用Object.defineProperty()
?由于这个方法是针对于对象的某一个属性的呀,对数组来讲不合适。
因此对于这道题,咱们也许可使用Proxy
代理每次传入进来的下标,也就是重写一下数组的get
方法,在这个方法中咱们去处理这方面的逻辑,一块儿来看看代码吧😊:
function createArr (...elements) {
let handler = { get (target, key, receiver) { // 第三个参数传不传均可以 let index = Number(key) // 或者 let index = ~~key if (index < 0) { index = String(target.length + index) } return Reflect.get(target, index, receiver) } } let target = [...elements] // 建立一个新数组 return new Proxy(target, handler) } var arr1 = createArr(1, 2, 3) console.log(arr1[-1]) // 3 console.log(arr1[-2]) // 2 复制代码
「注意点:」
get
接收到的第二个参数key
表示的是数组下标,它是字符串形式,因此须要转为Number
,固然方法有不少种了,使用Number()
也能够,使用~~
双非按位取反运算符也能够。对比于Number()
的好处就是Number(undefined)
会转换为NaN
;可是使用~~
能保证一直是数字,~~undefined === 0
。(什么?你还不知道区别?那你得看霖呆呆的这篇文章了:JS中按位取反运算符~及其它运算符)
接下来只须要判断一下传入进来的下标是否是小于0的,小于0的话加上数组的长度就能够了
而后返回index
这一项使用的是Reflect.get(target, index)
。什么?为何不直接用target[index]
?固然这样也能够,对比target[index]
的区别就是Reflect.get(target, index)
若是传入的target
不是一个Object
的话(数组也属于对象),就会报一个类型错误TypeError
,而target[index]
返回的会是一个undefined
。好比这样:
var obj = 5
console.log(obj['b']) // undefined console.log(Reflect.get(obj, 'b')) // Uncaught TypeError: Reflect.get called on non-object 复制代码
「扩展点:」
呆呆这边主要是想扩展一下get
的第三个参数receiver
(接受者),在MDN
上的解释是:
若是target
对象中指定了getter
,receiver
则为getter
调用时的this
值。
来看个例子理解一下😊。
案例一
例如咱们开始有这么一个对象:
var obj = {
fn: function () { console.log('lindaidai') } } 复制代码
如今使用Proxy
来赋值到obj1
中:
var obj = {
fn: function () { console.log('lindaidai') } } var obj1 = new Proxy(obj, { get (target, key, receiver) { console.log(receiver === obj1) // true console.log(receiver === target) // false return target[key] } }) obj1.fn() 复制代码
能够看到,receiver
表示的是obj1
这个新的代理对象,target
表示的是被代理的对象obj
。
因此,receiver
能够表示「使用代理对象自己」。
案例二
另外一种状况,receiver
也能够表示是「从其继承的对象」。
var proxy = new Proxy({}, {
get (target, key, receiver) { return receiver; } }) console.log(proxy.getReceiver === proxy) // true var inherits = Object.create(proxy) console.log(inherits.getReceiver === inherits) // true 复制代码
这个案例中,我新建了一个空对象的代理对象proxy
,使用proxy.getReceiver
获取它的receiver
,发现它就是代理对象自己。
而若是我将这个代理对象做为一个原型对象,建立出一个新的对象inherits
,也就是实现了原型式继承,那么这时候receiver
的值就是这个被继承的对象inherits
。
「总结」:
Proxy
代理,来改变每次获取数组的值。
Proxy
的
get
中,第二个参数是字符串,即便传入的是数组下标。
Number()
的好处就是
Number(undefined)
会转换为
NaN
;可是使用
~~
能保证一直是数字,
~~undefined === 0
。
target[index]
的区别就是
Reflect.get(target, index)
若是传入的
target
不是一个
Object
的话(数组也属于对象),就会报一个类型错误
TypeError
,而
target[index]
返回的会是一个
undefined
。
Proxy
的
get
中,第三个参数
receiver
一般为使用代理对象自己或从其继承的对象。
IE8
如下
addEventListener
可有冒泡,可有捕获;
attachEvent
只有冒泡,没有捕获。
on
,后者带
on
this
指向当前元素,后者指向
window
第三个参数涉及到冒泡和捕获,是true
时为捕获,是false
则为冒泡。
或者是一个对象{passive: true}
,针对的是Safari
浏览器,禁止/开启使用滚动的时候要用到。
div {
width: 200px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } 复制代码
div {
width: 200px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; } 复制代码
该方法适用于WebKit浏览器及移动端。
「跨浏览器兼容方案:」
p {
position:relative; line-height:1.4em; /* 3 times the line-height to show 3 lines */ height:4.2em; overflow:hidden; } p::after { content:"..."; font-weight:bold; position:absolute; bottom:0; right:0; padding:0 20px 1px 45px; } 复制代码
你盼世界,我盼望你无bug
。这篇文章就介绍到这里。
您每周也许会花48
小时的时间在工做💻上,会花49
小时的时间在睡觉😴上,也许还能够再花20
分钟的时间在呆呆的7道题上,日积月累,我相信咱们都能见证彼此的成长😊。
什么?你问我为何系列的名字叫DD
?由于呆呆
呀,哈哈😄。
喜欢「霖呆呆」的小伙还但愿能够关注霖呆呆的公众号 LinDaiDai
或者扫一扫下面的二维码👇👇👇。
我会不定时的更新一些前端方面的知识内容以及本身的原创文章🎉
你的鼓励就是我持续创做的主要动力 😊。
本文使用 mdnice 排版