继续磕面经(前端)
js的基本数据类型
Undefined、Null、Boolean、Number、String五种基本数据类型
获取变量的数据类型有哪些方法
-
typeof
,返回六种结果:undefined、boolean、number、string、object、functiontypeof ''; // string typeof 1; // number typeof true; // boolean typeof undefined; // undefined typeof null; //object typeof []; // object typeof new Function(); //function typeof new Date(); //object typeof new RegExp(); //object
-
instanceof
,判断是否是一个类的实例true instanceof Boolean; // false 1 instanceof Number; // false '' instanceof String; // false [] instanceof Array; // true ({}) instanceof Object; // true (function(){}) instanceof Function; // true new Boolean(true) instanceof Boolean; // true
instanceof
实现原理,沿着原型链寻找:function myInstanceof(left, right) { left = left.__proto__; right = right.prototype; while (true) { if (left === null) return false; if (left === right) return true; left = left.__proto__; } }
-
constructor
,一个类的constructor会指向自己的引用。需要注意的是:
null
和undefined
是无效的对象,因此没有constructor,需要通过typeof来判断。- JS对象的constructor是不稳定的。当开发者重写prototype后,原有的constructor会丢失,constructor会默认为Object。
''.constructor == String; // true (1).constructor Number; // true true.constructor == Boolean; // true new Function().constructor == Function; // true new Date().constructor == Date; //true
-
Object.prototype.toString
Object.prototype.toString.call(''); //[object String] Object.prototype.toString.call(1); //[object Number] Object.prototype.toString.call(true); //[object Boolean] Object.prototype.toString.call(undefined); //[object Undefined] Object.prototype.toString.call(null); //[object Null] Object.prototype.toString.call(new Function()); //[object Function] Object.prototype.toString.call(new Date()); //[object Date] Object.prototype.toString.call([]); //[object Array] Object.prototype.toString.call(new RegExp()); //[object RegExp] Object.prototype.toString.call(new Error()); //[object Error] Object.prototype.toString.call(document); //[object HTMLDocument] Object.prototype.toString.call(window); //[object global] window是全局对象global的引用 // 代码来自 红尘客栈-古月 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/mozuncangtianbaxue/article/details/77151598?utm_source=copy
JS的拷贝?
基本数据类型会新开辟一个数据段来保存值,
但是对象的拷贝实际上是拷贝了对实际对象的引用,我们可以把对象名看做指针。
深拷贝的方法
需要注意的是:slice()和concat()只深拷贝了一级属性。
-
递归复制所有属性
function deepClone(arg) { if (arg == null || typeof arg != 'object') return arg; let newObj = Array.isArray(arg) ? [] : {}; for (let key in arg) { if (arg[key] != null && typeof arg[key] == 'object') { newObj[key] = deepClone(arg[key]); } else { newObj[key] = arg[key]; } } return newObj; }
-
使用JSON的parse和stringify
function deepClone(arg) { return typeof arg == 'object' ? JSON.parse(JSON.stringify(arg)) : arg; }
-
使用JQuery的extend方法
$.extend([deep], target, object1[, objectN ])
- 用于将一个或多个对象的内容合并到目标对象
- 如果多个对象具有相同的属性,则后者会覆盖前者的属性值
function deepClone(arg) { if (arg == null || typeof arg != 'object') return arg; if (arg instanceof Array) return $.extend(true,[],arg); else return $.extend(true,{},arg); }
CSS单位有哪些
相对长度
单位 | 描述 |
---|---|
em | 它是描述相对于应用在当前元素的字体尺寸,所以它也是相对长度单位。一般浏览器字体大小默认为16px,则2em == 32px; |
ex | 依赖于英文子母小 x 的高度 |
ch | 数字 0 的宽度 |
rem | 根元素(html)的 font-size |
vw | viewpoint width,视窗宽度,1vw=视窗宽度的1% |
vh | viewpoint height,视窗高度,1vh=视窗高度的1% |
vmin | vw和vh中较小的那个。 |
vmax | vw和vh中较大的那个。 |
% | 介绍链接 |
绝对长度
单位 | 描述 |
---|---|
cm | 厘米 |
mm | 毫米 |
in | 英寸 (1in = 96px = 2.54cm) |
px | 像素 (1px = 1/96 of 1in) |
pt | point,大约1/72英寸; (1pt = 1/72in) |
pc | pica,大约6pt,1/6英寸; (1pc = 12 pt) |
网页渲染的流程
参考:https://www.cnblogs.com/dojo-lzz/p/3983335.html
页面解析渲染该过程主要分为以下步骤:
- 解析HTML
- 构建DOM树
- DOM树与CSS样式进行附着构造呈现树
- 布局
- 绘制
- 浏览器怎么知道收到的包是html文件(content-type)
- CSS会阻塞DOM解析么(不会阻塞DOM解析,会阻塞DOM渲染,阻塞后面的JS执行)
- 知道哪些content-type(参考链接)
- text/html :HTML格式
- text/css:CSS格式
- text/plain :纯文本格式
- text/xml :XML格式
- image/gif :gif图片格式
- image/jpeg :jpg图片格式
- image/png :png图片格式
- application/xml : XML数据格式
- application/x-javascript:.js
- application/json : JSON数据格式
- application/pdf : pdf格式
- application/msword : Word文档格式
- application/octet-stream : 二进制流数据(如文件下载)
- application/x-www-form-urlencoded : POST 提交数据
- multipart/form-data : 表单上传文件
- bfc(看这里)
- 清浮动的方法(父元素:after,结尾空div clear,父元素定义height,overflow,父元素table,结尾br clear)
- 水平方向有margin叠加么(没有)
JS继承
- 原型链继承
- 借用构造函数
- 组合继承
- 原型式继承(浅拷贝)
- 寄生式继承(原型式继承的增强版)
- 寄生组合式继承
- 原型继承可以继承非原型属性么
- 修正constructor
- apply/call方法和原型方法的区别
vue:v-model
双向绑定
<input v-model="searchText">
等价于:
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
设计模式
单例模式
- 用来解决哪些问题——一个全局使用的类频繁地创建与销毁。
- 只能用闭包实现么
- 写个单例模式
// es5实现
// 最简单的实现,没有什么封装性
var singleton1 = {
attr: 1,
method: function() {return this.attr;}
};
// 利用构造函数内部解析,不安全
function singleton2 {
if (singleton2.instance !== undefined) {
return singleton2.instance;
}
this.name = "xxx";
this.age = "20";
singleton2.instance = this;
}
// 利用闭包
var singleton3 = (function() {
var instance;
function constructor() {
// blabla
}
function getInstance() {
if (instance === undefined) {
instance = new constructor();
}
return instance;
}
return {
getInstance: getInstance;
};
})();
// ================================================
// es6 实现
// 懒汉式单例
class Singleton1 {
// 构造方法
constructor() {
// this.xxx = xxx
}
static getInstance() {
if (!this.instance) {
this.instance = new Singleton1()
}
return this.instance
}
}
// 饿汉式单例
class Singleton2 {
// 构造方法
constructor() {
// this.xxx = xxx
}
static getInstance() {
return this.instance
}
}
Singleton2.prototype.instance = new Singleton2()
预解析
在当前作用域下,js运行之前,会把带有var和function关键字的事先声明,并在内存中安排好。然后再从上到下执行js语句。函数声明会最先得到提升,然后是变量声明。
DOM
- 已知父节点获取第一个子节点(parentObj.firstChild)
- 查兄弟节点(previousSibing前一个,nextSibing后一个)
- 在某个子节点后面插入节点(利用nextSibing、lastChild、insertBefore()、appendChild())
对象的存储方式
实际存储在堆中,在栈中存储的是堆内存储地址。
所以可以把变量名看做指针。
内存回收方式
标记清除、引用计数(问题:循环引用,IE9之前BOM和DOM是COM实现的,垃圾收集采用的是引用计数,因此也会出现问题)
String为什么有length属性
基本包装类型
已知一个function ClassA() {},如何使得new ClassA()和ClassA()返回的值都是新的实例
函数内部判断this是否为window
用数据结构表示项目之间的依赖
双向链表?map?不知道。。。
判断一个图有没有环
无向图:不断去掉度为1的点
有向图:拓扑排序
从输入url到显示完成了什么
- 用户输入URL地址
- 浏览器解析URL解析出主机名
- 浏览器将主机名转换成服务器ip地址(浏览器先查找本地DNS缓存列表 没有的话 再向浏览器默认的DNS服务器发送查询请求 同时缓存)
- 浏览器将端口号从URL中解析出来
- 浏览器建立一条与目标Web服务器的TCP连接(三次握手)
- 浏览器向服务器发送一条HTTP请求报文
- 服务器向浏览器返回一条HTTP响应报文
- 浏览器解析文档
- 如果文档中有资源 重复6 7 8 动作 直至资源全部加载完毕
- 关闭连接
- 渲染页面
- 浏览器会不会缓存dns
- 会,不同浏览器缓存时间不一样
- https多了什么步骤
- https: http + 通信加密 + 证书 + 完整性保护,http secure
- 证书可以证明服务器或客户端的身份
- ssl: secure socket layer,安全套接层
- 多了SSL安全套接层。HTTP直接和TCP通信。当使用SSL时,则变为先和SSL通信,再由SSL和TCP通信。所以HTTPS可以看做身披SSL协议外壳的HTTP。
- 假如客户端最大下行10m,服务端最大上行100m,服务端会直接以10m的速率发包么(加增乘减,AIMD)
- 上行就是上传的速度,下行就是下载的速度
- 加法增大(Additive Increase):执行拥塞避免算法后,使拥塞窗口缓慢增大,以防止网络过早出现拥塞
- 乘法减小(Multiplicative Decrease):不论在慢开始阶段或拥塞避免阶段,只要出现超时,就把慢开始门限值减半(当前拥塞窗口的一半)
- 将这两种算法结合起来被称为AIMD算法
- 浏览器解析数据是全部收到才解析还是边收边解析
- 如果加载
<link>
需要十秒,分别在head和body那么加载时用户会看到什么 - script,同上,还有外联/内联
<!-- 作者:toln
链接:https://www.zhihu.com/question/61309490/answer/304391361
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 -->
HTML的加载不会受到js加载的影响
页面渲染的大致过程为,先下载解析HTML并建立DOM树,再解析css绘制渲染树。前者搭建页面结构,后者增添页面样式。而在建立DOM树的过程就会遇到诸如img、外联css和script标签,此时就要加载外部资源了。加载资源是由单独的下载线程进行异步加载的,浏览器会并行加载,不过具体并行最大数量是有一定限制的,不同浏览器可能不一样。但是加载css和js资源比较特殊,它们的加载会影响页面渲染。css加载不会阻塞DOM树解析,但会阻塞渲染(这是由于渲染依赖于css,如果不等css加载完就渲染的话那么等css加载解析完又得重新渲染,可能又要重绘或者回流)。对于js资源的加载,则会阻塞DOM树的构建和渲染,除非设置了script标签的异步属性。
放在head中会在解析DOM树和渲染页面前就加载,并阻塞页面。js正常情况下加载完就会立即执行,在js脚本中只能访问当前script以上的DOM,脚本执行结束后再继续解析DOM。js执行引擎和页面渲染是由不同的线程来执行,但这两者是互斥的,也就是说js执行过程是无法构建DOM和渲染页面的。这是一种优化机制,由于js可能会对DOM及样式进行修改,如果解析js过程中同时构建DOM,就可能造成前后内容不一致或者重复构建。所以应该把script放在body中,使页面更快完成渲染。
实现parse函数解析?b=1&c=2这样的字段
function myParse(arg) {
arg = arg.split('?')[1].split('&');
let obj = {};
for (let i = 0; i < arg.length; i++) {
obj[arg[i].split('=')[0]] = arg[i].split('=')[1];
}
return obj;
}
箭头函数的区别,能当做构造函数么
ES6如何获取函数参数
rest
setTimeout准时么
不准时,只是到了时间后加入执行队列
ES6手写观察者模式
观察者模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。
产生0-100的随机数
Math.floor(Math.random()*100);
http报文结构,header有哪些字段
起始行、首部、主体。之间由CR+LF(回车换行)隔开。
header:首部
跨域
只有当 域名、协议、端口 都相同时才视为同源。
方法:
- 跨资源共享
- document.domain
- 图像ping
- jsonp
- comet
- websocket
手写所有排序算法和DFS、BFS
快排、堆排、基数排序
// 插入排序
function insertionSort(arr) {
for (var i = 1; i < arr.length; i++) {
var tmp = arr[i];
var j = i-1;
while (j >= 0 && tmp < arr[j]) {
arr[j+1] = arr[j--];
}
arr[j+1] = tmp;
}
return arr;
}
// 二分插入排序
function binaryInsertionSort(arr) {
for (var i = 1; i < arr.length; i++) {
var tmp = arr[i], left = 0, right = i-1;
while (left <= right) {
var mid = parseInt((left + right) / 2);
if (arr[mid] < tmp) left = mid + 1;
else right = mid-1;
}
for (var j = i; j > left; j--) {
arr[j] = arr[j-1];
}
arr[left] = tmp;
}
return arr;
}
盒模型
标准盒模型和IE盒模型
session和cookie区别
替换元素
浏览器根据元素的标签和属性,来决定元素的具体显示内容
img、input、textarea、select、obejct、button、label都是替换元素(置换元素)
面向对象的特性
封装继承多态
封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
继承:可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
多态:实现多态,有二种方式:覆盖,重载。
同步异步区别
- 同步方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。
- 异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作。而,异步方法通常会在另外一个线程中,“真实”地执行着。整个过程,不会阻碍调用者的工作。
js异步加载方法
defer、async、创建script插入到DOM中
串行和并行
串行是指多个任务时,各个任务按顺序执行,完成一个之后才能进行下一个。
并行指的是多个任务可以同时执行。
数据库index及实现
进程和线程
方面 | 进程 | 线程 |
---|---|---|
根本区别 | 操作系统资源分配的基本单位 | 任务调度和执行的基本单位 |
开销方面 | 每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销 | 线程可以看做是轻量级的进程。同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销很小 |
所处环境 | 操作系统中多个进程可以并发运行 | 同一个进程中可以有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行) |
内存分配 | 系统在运行时会为每个进程分配不同的内存空间 | 除了CPU外,系统不会为线程分配内存(线程使用的资源来自其所属进程的资源),线程组之间只能共享资源 |
包含关系 | 进程可以包含多个线程,且这些线程可以并发运行 | 线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程 |
进程间通信方法
- 共享内存
- 信息传递
- 管道通信
进程或线程的同步方法
管程、信号量
尾递归
若一个函数在尾位置调用本身(或是一个尾调用本身的其他函数等),则称这种情况为尾递归,是递归的一种特殊情形。而形式上只要是最后一个return语句返回的是一个完整函数,它就是尾递归。这里注意:尾调用不一定是递归调用,但是尾递归一定是尾调用。
position
浮动
圣杯布局、双飞翼布局
<!DOCTYPE html>
<html>
<head>
<title>圣杯布局</title>
<style type="text/css">
.main, .left, .right {
position: relative;
float: left;
min-height: 150px;
}
.container {
padding: 0 300px 0 200px;
}
.main {
width: 100%;
background-color: red;
}
.left {
width: 200px;
margin-left: -100%;
left: -200px;
background-color: green;
}
.right {
width: 300px;
margin-left: -300px;
left: 300px;
background-color: blue;
}
</style>
</head>
<body>
<div class="container">
<div class="main"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>双飞翼布局</title>
<style type="text/css">
.container, .left, .right {
position: relative;
float: left;
min-height: 150px;
}
.main {
padding: 0 300px 0 200px;
}
.container {
width: 100%;
background-color: red;
}
.left {
width: 200px;
margin-left: -100%;
background-color: green;
}
.right {
width: 300px;
margin-left: -300px;
background-color: blue;
}
</style>
</head>
<body>
<div class="container">
<div class="main"></div>
</div>
<div class="left"></div>
<div class="right"></div>
</body>
</html>
动画实现div无限旋转
@keyframes rotate{
from {transform: rotate(0deg);}
to {transform: rotate(359deg);}
}
div {
animation: rotate 3s linear infinite;
}
前端性能优化
https://blog.csdn.net/mapbar_front/article/details/79836443
304实现原理
如果web服务器返回304响应,则表示此请求的本地缓存是最新的,可以直接使用。这种方法可以节省带宽,避免重复响应。
webSocket是哪一层的
应用层
实现add(1)(2)(3) == 6
function add(num) {
num += add.num?add.num:0;
add.num = num;
return add;
}
add.valueOf = function() {
return add.num;
};
实现类似于(10).add(5).reduce(2).add(1)的链式调用
Number.prototype.add = function(num) {return this+num;};
Number.prototype.reduce = function(num) {return this-num;};
js是单线程的,如何实现定时
setTimeout
ES6代理
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
http://es6.ruanyifeng.com/#docs/proxy
Object.create()
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
计算一个数转换成二进制后1的个数
function oneCount(num) {
var re = 0;
num = num.toString(2);
for (var i = 0; i < num.length; i++) {
if (num[i] == '1') re++;
}
return re;
}
HTTP长连接
HTTP/1.1开始Connection:keep-alive
状态码5xx
服务器端问题
https默认端口
443
tcp连接过程中的状态考察
https://blog.csdn.net/qwertyupoiuytr/article/details/68938963
三次握手四次挥手详细
http2.0
多路复用和1.x请求的区别
unsigned int类型扩展长度
一个长度为一百万的数组中,超过一半都是某一个值,求这个值
https://blog.csdn.net/bzfys/article/details/73733917
渐进增强和优雅降级
渐进增强(Progressive Enhancement):一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。
优雅降级(Graceful Degradation):一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用,然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览。
没有辅助空间的情况下交换两个数的值
function swap1(a, b) {
b = a + b;
a = b - a;
b = b - a;
}
// 使用异或
function swap2(a, b) {
b = a ^ b;
a = b ^ a;
b = b ^ a;
}
前端安全
XSS——跨站脚本攻击
CSRF——跨站请求伪造
SQL注入
let暂时性死区和块级作用域
类数组
对于一个普通的对象来说,如果它的所有property名均为非负整数,同时也有相应的length属性,那么虽然该对象并不是由Array构造函数所创建的,它依然呈现出数组的行为,在这种情况下,这些对象被称为“类数组对象”。
与普通对象不同的是,类数组对象拥有一个特性:可以在类数组对象上应用数组的操作方法。
var o ={0:42,1:52,2:63,length:3}
console.log(Array.prototype.join.call(o));//“42,52,63”
console.log(Array.prototype.slice.call(o,1,2));//52
在浏览器环境中,document.getElementsByTagName()
语句返回的就是一个类数组对象。
在function调用中,function代码内的arguments
变量(保存传入的参数)也是一个类数组对象。
在ECMAScript 5标准中,字符串string就是一个只读的类数组对象:
var s = "History";
console.log(s[3]);//"t"
console.log(Array.prototype.join.call(s, " "));//"H i s t o r y"
for in 缺点
for..in循环会把原型(prototype)中方法与属性给遍历出来,所以这可能会导致代码中出现意外的错误。
为了避免这个问题,我们可以使用对象的hasOwnProperty()方法来避免这个问题。
forEach()
ES6中map遍历实现原理
数组去重
死锁
https详细过程
加密算法,对称还是非对称。md5,SHA,AES
模块化
webpack、AMD、CMD
数组的各种方法
内存换页算法
事件循环
ajax调用中,后台数据返回线程和前端UI线程是怎样通信和交互的,说一下实现原理
手写封装jsonp
function myCallback(data) {
console.log(data);
}
function jsonp(url, data, callback) {
if (data == 'string') {
callback = data;
data = {};
}
url += url.indexOf('?') == -1 ? '?' : '&';
url += 'callback=' + callback;
for (var key in data) {
url += '&' + key + '=' + data[key];
}
var script = document.createElement('script');
script.setAttribute('src', url);
document.querySelector('head').appendChild(script);
}
事件委托
也叫事件代理。
利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
TCP和UDP
soket阻塞模式
doctype
AJAX实现原理,手写实现
使用XMLHttpRequest实现
transform实现垂直居中
.center {
position: relative;
top: 50%;
transform: translateX(-50%);
}
call、apply、bind
bind返回修改this后的函数
call和apply立即执行,call顺序传参,apply传入数组
vuex流程
vue生命周期
前端缓存机制
js多位数字每隔三位加一个逗号
function addCommas0(num) {
num = (num || 0).toString();
var re = '';
while (num.length > 3) {
re = ',' + num.slice(-3) + re;
num = num.slice(0, num.length-3);
}
if (num) re = num + re;
return re;
}
function addCommas1(num) {
return num.toLocaleString();
}
function addCommas2(num) {
return (num || 0).toString().replace(/\B(?=(?:\d{3})+\b)/g, ',')
}
其中正则方法参考自https://www.cnblogs.com/sivkun/p/7123963.html
\d 等价于[0-9],表示数字字符
关于\b和\B可以看这个,很易懂
(?=(?:\d{3})+\b)) 里的 (?= ) 部分表示匹配一个位置,这个位置之后的内容符合这个括号里的条件,也就是 (?:\d{3})+\b
()表示捕获分组,()会把每个分组里的匹配的值保存起来,使用$n(n是一个数字,表示第n个捕获组的内容)
(?:)表示非捕获分组,和捕获分组唯一的区别在于,非捕获分组匹配的值不会保存起来
(?:\d{3})+\b 表示一串长度可以被三整除的数字直至末尾
移动端适配
https://blog.csdn.net/chenjuan1993/article/details/81710022
移动端的性能优化
https://blog.csdn.net/u010683915/article/details/71043188
实现getElementsByClassName
function getElementsByClassName(className) {
if (document.getElementsByClassName) {
return document.getElementsByClassName(className);
} else {
var elements = [];
var allNodes = document.getElementsByTagName('*');
for (var i = 0; i < allNodes.length; i++) {
var tmpClassNames = allNodes[i].className.replace(/\s+/g,',').split(',');
for (var j = 0; j < tmpClassNames.length; j++) {
if (tmpClassName[j] == className) {
elements.push(allNodes[i]);
break;
}
}
}
return elements;
}
}
DOM 选择器
document.getElementById()
——元素id在ie8以下的浏览器不区分id大小写,而且也返回匹配的name属性的元素
document.getElementsByName()
——只有部分标签name可生效(表单、表单元素、img、iframe)
document.getElementsByTagName()
document.getElementsByClassName()
——ie8和ie8以下的ie版本中没有
CSS选择器:(不是实时的)
在css中怎么选,这里就怎么选
document.querySelector()
document.querySelectorAll()
Web前端打包工具
https://baijiahao.baidu.com/s?id=1577252811128016864&wfr=spider&for=pc
webpack
首选
gulp
其次
grunt
已经落伍
jquery选择器实现
浏览器最小显示的字体大小 如果想要显示更小怎么办
12px transform
commomJS AMD CMD es6用的哪个
https://www.cnblogs.com/dongdongseven/p/7724106.html
$documnent.ready() VS window.onload() 哪种先执行
$document.ready()
在DOM加载完毕时执行
window.onload()
在整个页面所有资源都加载完成时执行
属性getter和setter
由getter
和setter
定义的属性称为存储器属性。
当程序查询存储器属性的值时,JavaScript调用getter
方法(无参数)。
当程序设置存储器属性的值时,JavaScript调用setter
方法,将赋值表达式右侧的值当做参数传入setter
。可以忽略setter
的返回值。
如果属性同时具有setter
和getter
方法,那么它是一个读/写属性。
如果只有getter
方法,那么就是一个只读属性。
如果只有setter
方法,那么就是一个只写属性,读取只写属性总是返回undefined。
var p = {
// 数据属性
x: 1.0,
y: 1.0,
// 存储器属性
get r() {
return Math.sqrt(this.x*this.x + this.y*this.y);
},
set r(newValue) {
var oldValue = Math.sqrt(this.x*this.x + this.y*this.y);
var ratio = newValue/oldValue;
this.x *= ratio;
this.y *= ratio;
}
};
Object.definePropoty()
Object.defineProperty(obj, prop, descriptor)
obj
要在其上定义属性的对象。
prop
要定义或修改的属性的名称。
descriptor
将被定义或修改的属性描述符。
configurable | enumerable | value | writable | get | set | |
---|---|---|---|---|---|---|
数据描述符 | Yes | Yes | Yes | Yes | No | No |
存取描述符 | Yes | Yes | No | No | Yes | Yes |
var o = {}; // 创建一个新对象
// 在对象中添加一个属性与数据描述符的示例
Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : true
});
// 对象o拥有了属性a,值为37
// 在对象中添加一个属性与存取描述符的示例
var bValue;
Object.defineProperty(o, "b", {
get : function(){
return bValue;
},
set : function(newValue){
bValue = newValue;
},
enumerable : true,
configurable : true
});
o.b = 38;
// 对象o拥有了属性b,值为38
// o.b的值现在总是与bValue相同,除非重新定义o.b
// 数据描述符和存取描述符不能混合使用
Object.defineProperty(o, "conflict", {
value: 0x9f91102,
get: function() {
return 0xdeadbeef;
}
});
// throws a TypeError: value appears only in data descriptors, get appears only in accessor descriptors
解释性语言和编译性语言
计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。
翻译的方式有两种,一个是编译,一个是解释。两种方式只是翻译的时间不同。
解释性语言的定义:
解释性语言的程序不需要编译,在运行程序的时候才翻译,每个语句都是执行的时候才翻译。这样解释性语言每执行一次就需要逐行翻译一次,效率比较低。
现代解释性语言通常把源程序编译成中间代码,然后用解释器把中间代码一条条翻译成目标机器代码,一条条执行。
编译性语言的定义:
编译性语言写的程序在被执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,比如exe文件,以后要运行的话就不用重新翻译了,直接使用编译的结果就行了(exe文件),因为翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高。
代码三要素
可读性
可维护性
可变更性