最近笔试的时候,遇到一些常考的前端知识点,这里总结一下,方便回顾复习。
1. CSS中可以继承的属性?
| 不可继承属性 | 子元素继承属性 | 列表元素可以继承 | 表格元素可以继承 | 都可以继承属性 |
|---|---|---|---|---|
| display、margin、padding、border、background、width、height、overflow、position系列、float、clear、table-layout、vertical-align、page-bread-before/after、unicode-bidi | letter-spacing、word-spacing、white-space、line-height、color、font系列、text-decoration、text-transform、direction、text-indent、text-align | list-style系列 | border-collapse | visibility、cursor |
对于不可继承的属性,如果希望子元素可以保持和父元素一致,可以将该属性值设置为inherit
border: inherit;
2. sessionStorage数据共享
localStorage存储的数据能够在客户端本地永久保存。 同域的任何页面都可以访问到localStorage存储的数据。但sessionStorage与localStorage有着较大的不同,简述如下:
- sessionStorage受到同源策略限制。
- sessionStorage存储数据还受到浏览器选项卡的限制。
- 手动新开一个选项卡,即便同域同URL,也不会共享sessionStorage数据。
- 当前选项卡关闭,sessionStorage中存储的数据也随之被销毁。
数据共享方式:
首先要明确一个概念,在新选项卡或者窗口打开一个新的页面,会新创建一个sessionStorage会话。 手动新开一个选项卡,即便同域同URL,也不会共享Sessionstorage数据。但是并不是说就没有办法共享sessionStorage存储的数据,准确的说不是共享,而是拷贝一份。
- 通过手动方式新开一个选项卡或者窗口不会共享数据。
- 通过JavaScript或者链接标签打开同源页面会共享数据(准确说是拷贝一份),两者是独立的。
假设A页面通过sessionStorage存储一些数据,页面中有一个链接指向同源的B页面。 点击链接,在新的选项卡打开B页面,那么A页面的数据会被B页面共享(事实是拷贝了一份)。 两个页面的数据是相互独立的,在B页面删除一条记录,并不会影响A页面中的数据。
3. img标签中title属性和alt属性?
alt 属性(图片描述):
当图片加载不出来的时候,就会在图片未显示的地方出现一段 alt 设置的属性内容。【这个属性的作用是为了给未加载的图片显示提示信息,即使在网络比较差的时候,用户也可以知道图片的内容,从而方便用于浏览网页,同时程序员对网站维护的时候也能更快地查找问题。】
浏览器的搜索引擎可以通过 alt 属性的文字描述来获取图片。
title 属性(图片解释说明):
title 属性可以用在任何元素上,当用户把鼠标移动到元素上时,就会显示预先设置的 title 的内容,起到对图片说明的作用,实际上就是对图片的解释和备注。
1. img 标签中引用的图片不论是否正常显示,图片只设置 title 属性之后,当鼠标经过或者悬停在图片区域时,就能看到图片的文字描述。
2. 当图片仅仅设置 alt 属性的时候。当鼠标悬停或者经过图片区域的时候,可以看到该图片设置的 alt 属性的文字内容。
3. 如果图片设置了 title 和 alt 两个属性,鼠标悬停或者经过图片区域的时候,只会显示 title 属性设置的内容。
4. CSS 盒子模型中()是透明的,这部分可以显示背景()
A、padding
B、margin
C、border
D、content
参考答案:A
答案解析:
Margin(外边距) 清除边框外的区域,外边距是透明的。
Border(边框) - 围绕在内边距和内容外的边框。
Padding(内边距) - 清除内容周围的区域,内边距是透明的。
Content(内容) - 盒子的内容,显示文本和图像。
margin 清除周围的元素(外边框)的区域。margin 没有背景颜色,是完全透明的。
Padding(填充), 当元素的Padding(填充)(内边距)被清除时,所"释放"的区域将会受到元素背景颜色的填充。
5. 进程与线程的关系?
-
进程是资源分配的基本单位,线程是CPU调度和分派的基本单位
-
线程是进程的一部分,一个线程只能属于一个进程,一个进程可以有多个线程,但至少有一个线程
-
每个进程都有独立的代码和数据空间(程序上下文),程序间的切换开销大,
-
线程可看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程间切换开销小
-
在操作系统中能同时运行多个进程(程序)在同一个进程(程序)中多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)
-
系统在运行的时候会为每个进程分配不同的内存空间线程除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源
-
两者都是多任务编程的方式,都能够使用计算机的多核
-
进程的创建删除要比线程消耗更多的计算机资源
-
线程使用全局变量通信,更加简单,但是需要同步互斥操作
-
进程线程都
独立执行,有自己的特有资源如属性,id, 命令集等 -
线程可以
创建线程
6. 跨域的方式?
- 利用HTML5 postMessage
- 利用document.domain + frame的设置
- 通过服务器Nginx配置跨域
- 利用iframe + location.hash
- windows.name实现跨域数据传输
7. visiblity:hidden和display:none的区别?
作用不同:
visibility:hidden将元素隐藏,但是在网页中该占的位置还是占着。display:none将元素的显示设为无,即在网页中不占任何的位置。
使用后HTML元素有所不同:
visibility:hidden,使用该属性后,HTML元素(对象)仅仅是在视觉上看不见(完全透明),而它所占据的空间位置仍然存在,也即是说它仍具有高度、宽度等属性值。display:none,使用该属性后,HTML元素(对象)的宽度、高度等各种属性值都将“丢失”。
定义不同:
visibility属性指定一个元素是否是可见的。display这个属性用于定义建立布局时元素生成的显示框类型。
8. Vue的事件修饰符?
-
prevent:阻止默认事件(常用)
<!-- 阻止默认事件(常用) --> <a href="http://www.atguigu.com" @click.prevent="showInfo">点我提示信息</a>a标签的默认有跳转到href的行为,我们把默认行为禁用后,就不会跳转页面
-
stop:阻止事件冒泡(常用)
<div class="demo1" @click="showInfo"> <button @click.stop="showInfo">点我提示信息</button> <!-- 修饰符可以连续写 --> <a href="http://www.atguigu.com" @click.prevent.stop="showInfo">点我提示信息</a> </div> -
once:事件只触发一次(常用)
<button @click.once="showInfo">点我提示信息</button> -
capture:使用事件的捕获模式
<div class="box1" @click.capture="showMsg(1)"> div1 <div class="box2" @click="showMsg(2)"> div2 </div> </div> -
self:只有event.target是当前操作的元素时才触发事件
<div class="demo1" @click.self="showInfo">
<button @click="showInfo">点我提示信息</button>
</div>
9. javaScript与客户端交互是基于事件驱动的
10. History 对象是 window 对象的一部分,可通过 window.history 属性对其进行访问
11. Vue中通过ref属性获取DOM
12. npm包管理器是基于Node.js平台使用的
13. 看题说输出
function A(cName) {
if (cName) {
this.name = cName;
}
}
A.prototype.name = 'dingding';
let a = new A();
console.log('A', a.name); // 当你给A原型上加name属性,new出来的实例就可以访问得到。
function B(cName) {
this.name = cName;
}
B.prototype.name = 'ylai';
let b = new B();
console.log('B', b.name); // B new出来的实例身上本书有name,所以不会再顺着原型链往上找了
// // A dingding B ylai
14 看题说输出2
function Foo() {
//这里的getName没有var关键字,定义的是一个全局变量
getName = function () {
console.log(1);
};
// this的默认绑定,返回的是window
return this;
}
// 给Foo定义一个getName静态属性存储了一个匿名函数
Foo.getName = function () {
console.log(2);
};
// 给Foo的原型定义getName方法
Foo.prototype.getName = function () {
console.log(3);
};
// 定义全局的getName方法,函数表达式
var getName = function () {
console.log(4);
};
// 声明一个叫getName的函数
function getName() {
console.log(5);
}
Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
// 关于运算符优先级的问题
new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); // 3
此题涉及的知识点众多,包括变量定义提升、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性及原型属性优先级等等。
第一问:
首先定义了一个Foo的函数,后为Foo创建了一个叫getName的静态属性存储了一个匿名函数,之后为Foo的原型对象新创建了一个叫getName的匿名函数。之后又通过函数变量表达式创建了一个getName的函数,最后再声明一个叫getName函数。
第一问的 Foo.getName() 自然是访问Foo函数上存储的静态属性,自然是2,没什么可说的。
第二问:
直接调用 getName 函数。既然是直接调用那么就是访问当前上文作用域内的叫getName的函数,所以跟1 2 3都没什么关系。此题有无数面试者回答为5。此处有两个坑,一是变量声明提升,二是函数表达式。
函数表达式 与 函数声明 重名 会覆盖函数声明
函数表达式最大的问题,在于js会将此代码拆分为两行代码分别执行。 例如下代码:
console.log(x);//输出:function x(){}
var x=1;
function x(){}
实际执行的代码为,先将 var x=1 拆分为 var x; 和 x = 1; 两行,再将 var x; 和 function x(){} 两行提升至最上方变成:
var x;
function x(){}
console.log(x);
x=1;
所以最终函数声明的x覆盖了变量声明的x,log输出为x函数。
同理,原题中代码最终执行时的是:
function Foo() {
getName = function () { alert (1); };
return this;
}
var getName;//只提升变量声明
function getName() { alert (5);}//提升函数声明,覆盖var的声明
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
getName = function () { alert (4);};//最终的赋值再次覆盖function getName声明
getName();//最终输出4
第三问:
第三问的 Foo().getName(); 先执行了Foo函数,然后调用Foo函数的返回值对象的getName属性函数。
Foo函数的第一句 getName = function () { alert (1); }; 是一句函数赋值语句,注意它没有var声明,所以先向当前Foo函数作用域内寻找getName变量,没有。再向当前函数作用域上层,即外层作用域内寻找是否含有getName变量,找到了,也就是第二问中的alert(4)函数,将此变量的值赋值为 function(){alert(1)}。
此处实际上是将外层作用域内的getName函数修改了。
注意:此处若依然没有找到会一直向上查找到window对象,若window对象中也没有getName属性,就在window对象中创建一个getName变量。
之后Foo函数的返回值是this,this的指向是由所在函数的调用方式决定的。而此处的直接调用方式,this指向window对象。
遂Foo函数返回的是window对象,相当于执行 window.getName() ,而window中的getName已经被修改为alert(1),所以最终会输出1
此处考察了两个知识点,一个是变量作用域问题,一个是this指向问题。
第四问:
直接调用getName函数,相当于 window.getName() ,因为这个变量已经被Foo函数执行时修改了,遂结果与第三问相同,为1
第五问:
第五问 new Foo.getName(); ,此处考察的是js的运算符优先级问题。 点(.)的优先级高于new操作,相当于是:
new (Foo.getName)();
所以实际上将getName函数作为了构造函数来执行,遂弹出2
第六问:
第六问 new Foo().getName() ,首先看运算符优先级括号高于new,实际执行为
(new Foo()).getName()
先执行Foo函数,而Foo此时作为构造函数却有返回值,所以这里需要说明下js中的构造函数返回值问题。
返回的是this,而this在构造函数中本来就代表当前实例化对象,遂最终Foo函数返回实例化对象。
之后调用实例化对象的getName函数,因为在Foo构造函数中没有为实例化对象添加任何属性,遂到当前对象的原型对象(prototype)中寻找getName,找到了。
遂最终输出3。
第七问:
new new Foo().getName(); 同样是运算符优先级问题
最终实际执行为:
new ((new Foo()).getName)();
先初始化Foo的实例化对象,然后将其原型上的getName函数作为构造函数再次new。
遂最终结果为3