TODO
Object.defineproperty()margin垂直重叠字的基线深拷贝与浅拷贝未声明的变量会自动升级为全局变量的原因HTTPS与HTTP> ~ +使用rem设置元素宽高在chrome中的问题IOT 中pull-right/经纬度/地区输入小题
1 | var obj1 = { |
Object.defineProperty()
1 | Object.defineProperty(obj, prop, descriptor) |
该方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。与常见的直接使用.
和[]
不同,它能通过descriptor
参数定义属性的更多设定。
obj
要在其上定义属性的对象。
prop
字符串,要定义或修改的属性的名称。
descriptor/属性描述符
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。访问器描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。
/ | configurable | enumerable | value | writable | get | set |
---|---|---|---|---|---|---|
数据描述符 | yes | y | y | y | no | n |
存取描述符 | y | y | n | n | y | y |
configurable
设置属性描述符descriptor
是否能被修改,默认为flase;如果尝试去更改configurable:false
的属性描述符
内的属性则会报错:
1 | var a = { |
enumerable
设置属性是否能被枚举,默认为flase,不能被枚举;
1 | var a = { |
1 | var a = { |
value
默认为undefined
writable
仅当该属性的writable
为true
时,value
才能被赋值运算符改变。默认为 false
。
这样一道题:
1 | /** |
实例化构造函数时,新的实例都会刷新变量,因此使用通常的方法无法实现效果。
使用Object.defineProperty
,并设置writable: true
的解决方法:
1 | function Sequence() { |
get
给属性提供 getter 的方法
set
给属性提供 setter的方法,该方法将接受唯一参数,并将该参数的新值分配给该属性。
数据描述符
1 | var obj = {}; |
存取描述符
1 | var temp; |
参考:MDN web docs
margin的垂直重叠
两个或多个相邻的普通流中的块元素垂直方向上的 margin 会折叠
两个或多个
需要两个或两个以上的元素参与的行为,且折叠是相互行为,不存在 A 和 B 折叠,B 没有和 A 折叠的现象。
相邻
兄弟同级相邻
两个元素时兄弟,且二者之间没有其他元素:
1 | <div> |
此时二者的间距为20px,产生重叠;
若兄弟间有其他元素,则不会产生重叠,二者间距30px;
1 | <div> |
父子相邻
父子之间的margin-top
相邻或margin-bottom
相邻;
1 | <div style='margin-bottom:20px'> |
此时父级的margin-bottom
与子级的margin-bottom
相邻,产生重叠,对于父级外界而言,只取margin-bottom
最大值,即20px;
其他相邻
其实只要满足上下相邻,中间没有其他元素皆可。
普通流
相邻的浮动、inline-block
、absolute
定位的元素垂直方向的margin
不会发生重叠;
块元素
内联元素不可设置宽高和margin
。
垂直方向
只有在垂直方向才会发生重叠,水平方向不会。
margin重叠有什么意义
看起来有点奇怪的规则,其实有其现实意义。比如在我们使用p
元素排版段落时,p
元素默认外边距是16px,上下两个p
元素不会产生中间间隔32px的现象;
1 | <p>1111</p> |
如何使margin垂直方向不重叠
- 使用padding代替;
- 设置父级元素overflow: hidden/auto;
- 设置二者之一的元素
display: inline-block
; - 设置元素浮动或者绝对定位;
注:并不是所有的BFC都可以使margin垂直方向不重叠,设置overflow、display、浮动和绝对定位只是BFC的子集;
字的基线与vertical-align
字的基线
vertical-align
默认基线对齐baseline
1 | <div> |
1 | div { |
默认基线对齐:
Top
把元素的顶端与其他行中最高元素的顶端对齐
1 | .img-sm { |
效果:
Bottom
把元素的顶端与其他行中最低的元素的顶端对齐
1 | span { |
效果:
Middle
把元素的中部和父元素字体的中线对齐
1 | <div> |
1 | div { |
效果:
text-top & text-bottom
把元素的顶端与父元素字体的顶端对齐 & 把元素的底端与父元素字体的底端对齐
text-top:
text-bottom:
百分比或者长度
- %: 使用 “line-height” 属性的百分比值来排列此元素。允许使用负值,需要设置line-height;
- 长度:正负px;
以上两种只会让元素在父元素内上下移动,向上最多到父元素顶部,向下则可以出父元素
1 |
|
深拷贝与浅拷贝
总结一下:
基本数据类型:number,string,boolean,null,undefined五类,无需深拷贝,直接存在栈内;
引用数据类型:(Object类),有常规名值对的无序对象{a:1},数组[1,2,3],以及函数等。存储在栈中的是堆中的地址,浅拷贝只拷贝栈中地址,故需要深拷贝。
实现深拷贝:
- 递归赋值所有层级属性
- 使用
JSON.stringify()
和JSON.prase()
像使用slice() / concat() / Object.assign()
等只能深拷贝一层,不是真正的深拷贝。
未声明的变量会自动升级为全局变量的原因
~ > +
1 | <body> |
p~h1
选择和p
元素父级相同,在p
元素之后的元素,所以color
为yellow
的是 2 3
;
1 | <div class="foo"> |
.foo > h1
选择的是.foo
内的所有元素,但只选择一代,所有只有 1
才显示为红色;
1 | <div class="foo">11</div> |
.foo + .boo
选择的是.foo
之后紧邻且同级的.boo
元素。所以红色的为22
,33
并不会变红。
使用rem设置元素宽高在chrome中的问题
rem是相对于html根节点的长度单位。在使用rem替代px时,常设置:html: { font-size: 62.5% }
, 16px为默认字体大小,1rem = 62.5% * 16px = 10px
,方便计算,所以24px可以表示为2.4rem,即2.4 * 62.5% * 16px = 24px
。
但在chrome中由于浏览器默认最小字体为12px,所以导致1rem = 12px
,width:10rem
渲染出来是width:120px
,报道出了偏差…
解决
为了避免出现10px被设置为12px的问题,可将 62.5% 改为 625%,则1rem = 625% * 16px = 100px
:
1 | html: { |
100px可表示为1rem, 24px可表示为.24rem
小题
1 | var obj1 = { |
这涉及到this的引用
this是函数内部的一个特殊对象(或this引用)–它引用的是函数据以执行的环境对象。(来源于JavaScript高级程序设计)
this引用是一种在JavaScript的代码中随时都可以使用的只读变量。 this引用,引用(指向)的是一个对象,它有着会根据代码上下文语境自动改变其引用对象的特性。
- JavaScript是动态语言,this关键字在执行的时候才能确定是谁,所以this永远指向调用者,即对“调用对象”的引用。简单点说就是 调用的方法属于哪个对象,this就指向那个对象。根据函数调用方式的不同,this可以 指向全局对象,当前对象,或其他任意对象。this四个调用模式
因此,this只有在被调用时才确定指向,console.log(obj2.getAge())
的结果是obj2.age
,即30。
拓展:
动态语言:是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化,类型的检查是在运行时做的,优点为方便阅读,清晰明了,缺点为不方便调试。如JavaScript;
静态语言:静态类型语言的类型判断是在运行前判断(如编译阶段),比如C#、java。