前后端对接问题:
- 接口
- 跨域
队列是什么?:队列是先进先出(插队除外)。先进去的代码先执行。
[ ] + push + shift = 数组。我们可以认为JS的数组是队列的一种实现。
栈:先进后出。像罐子里放东西,先放的东西会压在罐子底下,要拿的时候,最后才能拿出来。
栈的实现 = [ ] + push + pop
JS链表:一个节点连着一个节点,只要不是连着两个或多个节点。
proto 就等于next,是下一个节点的意思。
树:一个节点后面有两个或两个以上的节点。
树:一个节点后面有两个或两个以上的节点。像 window 就是树,里面有 (object, array, function) 等等节点。
typeof 和 instanceof的区别
ES6规范中有7种数据类型,分别是基本类型和引用类型两大类
基本类型(简单类型、原始类型):String、Number、Boolean、Null、Undefined、Symbol
引用类型(复杂类型):Object(对象、Function、Array)
1、typeof返回结果是该类型的字符串形式表示
(number、string、undefined、boolean、function、object)
注意
typeof对于原始类型来说,除了null都可以显示正确类型
typeof对于对象来说,除了函数都会显示object
2、instanceof是用来判断 A 是否为 B 的实例。
表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。
在这里需要特别注意的是:instanceof 检测的是原型。
万物皆对象,对象皆为空(null)。除了null之外,其余都有原型。
原型是一个对象,其他的对象可以通过原型属性继承,除了prototype。
__proto__是每个对象都有的属性,就连function也不除外。prototype是函数才有的属性。
__proto__不是一个规范的属性,只是部分浏览器实现了此属性。它所对应的标准属性是[[prototype]]。
所谓标识符,就是指变量、函数、属性的名字,或者函数的参数。
创建数组的方式:
- 利用
new
创建数组。var arr = new Array();
// 创建了一个空的数组 - 利用数组字面量创建数组。
var 数组名 = [ ];
// 创建了一个空的数组。
在数组里可以放任意的数据类型。我们数组里面的数据一定用逗号分隔。数组里面的数据,比如1,2。我们称为数组元素。
数组可以通过索引来访问、设置、修改对应的数组元素,我们可以通过“数组名[索引]
”的形式来获得数组中的元素。
这里的访问就是获取得到的意思。
如:
var arr = [1, red, true, 'xiaoming'];
console.log(arr[3]);
这样就可以得到最后一个数组元素 xiaoming 了。
注意:这里如果写成 console.log(arr[4]);, 索引是从0开始的,这里没有这个数组元素,所以返回的结果是undefined。
遍历:就是把数组的元素从头到尾访问一次。
形参是接收实参的。形参类似于一个变量,只不过这个形参不需要声明。
如果实参和形参的个数一致,则正常输出结果。
如果实参的个数多于形参的个数,会取到形参的个数,多出的不参与运算。
如果实参的个数少于形参的个数,多出的形参定义为undefined,输出结果为 NaN。
return:
- 返回值给调用者
return只会返回一个值,如果有多个值,以最后一个为准。 - 终止函数的执行
- 只要是函数它都会有返回值,函数如果没有return,则返回undefined。
break、continue、return的区别:
- break:结束当前的循环体(如:for,while)。
- continue:跳出本次循环,继续执行下次循环。(如:for,while)。
- return:不仅可以退出循环,还可以返回return语句中的值,同时还可以结束当前函数体内的代码。
所有函数都内置了一个arguments对象,arguments中存储了传递的所有实参。
arguments 是以一种伪数组的形式来进行展示的,因此可以进行遍历。
伪数组的特点:
- 具有length属性。
- 按索引方式存储数据。
- 不具有数组的push,pop等方法。
注意:只有函数才有arguments,而且每个函数都内置好了这个arguments。
undefined的四种场景
-
变量声明未赋值
-
函数参数没有传递
-
获取对象的不存在的属性
-
函数没有返回值
<a href = '#'> 删除</ a> 阻止a里面的href跳转,我们就不要用井号了,可以使用javascript: void(0); 或者 javascript:;
木马(Trojan [ˈtrəʊdʒən])是指可以控制另一台计算机的特定程序。
DPR也就是设备像素比
设备像素比(dpr) = 设备像素(分辨率)/设备独立像素(屏幕尺寸)
布局视窗:屏幕大小
视觉视窗:为了解决PC端网站在移动端显示不佳,布局视窗比设备屏幕宽度宽,一般为980
这行代码把视觉视窗大小设置成和布局视窗大小相等,这样我们在代码设置css像素时,设置的跟渲染出来效果也是一样。
屏幕分辨率基础概念说明
缩写 | 全称 | 说明 |
---|---|---|
PX | Device Pixels | 设备像素,指设备的物理像素 |
PX | CSS Pixels | CSS像素,指CSS样式代码中使用的逻辑像素 |
DOT | Dot | 点,屏幕或打印纸上的点,等同物理像素 |
DP | Density independent Pixels | 设备无关像素(Android长度单位),为1/160英寸,等同于CSS逻辑像素 |
SP | Scale independent Pixels | 缩放无关像素(Android字体单位),等同于CSS逻辑像素,但文字尺寸可调(单独缩放) |
DPR | Device Pixel Ratio | 设备像素比,指CSS逻辑像素对于物理像素的倍数 |
DPPX | Dots Per Pixel | 等同于DPR |
PPI | Pixel Per Inch | 屏幕上每英寸(2.54厘米)的像素点个数 |
DPI | Dots Per Inch | 屏幕或纸上每英寸(2.54厘米)的点个数,标准密度:传统打印=72;Windows=96;Android=160;iOS=163。 |
DPIR | DPI Ratio | DPI缩放比例,指DPI对于Windows标准DPI的倍数=DPI/96,等同于DPR |
变量不存在,访问会报错,报xxx is not defined.
对象不存在,访问会返回 undefined。
栈 stack;堆 heap
栈、堆都在运行内存中。
autocomplete: off 关闭表单里面的提示信息。
console.dir(newLi);
查找newLi
的属性。console.dir()可以显示一个对象所有的属性和方法。
在JS中可以使用自定义属性来方便自己的某些操作。
setAttribute(name, value) 是没有返回值的。
重绘重排,我们不可避免重绘重排,但是我们要优化页面,减少重绘重排。重排也称为“回流”。重排一定会引起重绘,但是重绘不一定重排。
块级作用域就是用花括号{}
进行包含的,如if{}
, for{}
等。
// Java中
if () {
int num = 10;
}
// 外面是不能调用num的。
// js 中
if (3 < 5) {
var num = 10;
}
console.log(num); // 是可以正常输出的。
作用域链:内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构我们称为“作用域链”。
作用域链就是采用的“就近原则”。小技巧:先要确认是否被调用,然后站在输出的目标出发,一层一层的往外查找。
我们JS引擎运行js分为两步:
- 预解析
- 代码执行
预解析:js引擎会把js里面所有的var(变量提升)还有function(函数提升)提升到当前作用域的最前面。如果函数内部也有var,需要在函数内部提升。
代码执行:按照代码书写的顺序,从上往下执行。
函数提升优先级高于变量提升,且不会被同名变量声明时覆盖,但是会被变量赋值后覆盖(CSDN)
var a = b = c = 9;
// 相当于 var a = 9; b = 9; c = 9; 只声明了一个a,其余两个没有声明,当全局变量看。
// 如果集体声明需要用逗号隔开。
// 集体声明:var a = 9, b = 9, c = 9;
// 相当于:var a = 9; var b = 9; var c =9;
属性:事物的特征,在对象中用属性来表示(常用名词)。方法:事物的行为,在对象中用方法来表示(常用动词)。
保存一个值时,可以使用“变量”,保存多个值(一组值)时,可以使用“数组”。如果要保存一个人的完整信息呢?数组也可以,但是很明显对象会更方便。
JS中的对象表达结构更清晰,更强大。
创建对象(object)的三种方式:
-
利用
字面量
来创建对象。 -
利用
new Object
来创建对象。 -
利用
构造函数
来创建对象。
利用字面量
来创建对象。
对象字面量:就是花括号{}
里面包含了表达这个具体事物(对象)的属性和方法。
var obj = {};
// 创建了一个空的对象
var obj = {
uname: '张三丰',
age: 18,
sex: '男',
sayHi: function () {
console.log('hi~');
}
}
// 1. 里面的属性或者方法我们采用键值对的形式,键为属性名,值为属性值。
// 2. 多个属性或者方法,中间用逗号隔开,最后一个不用跟逗号。
// 3. 方法冒号后面跟的是一个匿名函数。
使用对象:
- 调用对象的属性 我们采取
对象名.属性名
。这个小点(.),我们理解为“的”。
console.log(obj.uname);
- 调用属性还有一种方法,
对象名[‘属性名’]
这里面的属性名需要加引号。
console.log(obj['age']);
- 调用对象的方法:
对象名.方法名
obj.sayHi();
这里面的小括号不能少,千万别忘记添加小括号。
变量、属性、函数、方法的区别。
变量和属性的相同点:
他们都是用来存储数据的。
var num = 10;
var obj = {
age: 18
}
console.log(obj.age);
// 不可以写成 console.log(age);
变量和属性的不同点:
- 变量:单独声明并赋值。使用的时候直接写变量名。总结:单独存在。
- 属性:属性在对象里面的,不需要声明的。使用的时候必须是
对象.属性
,或者使用中括号,对象[]。
函数和方法的相同点:
- 都是实现某种功能,做某件事。
var num = 10;
var obj = {
age: 18,
fn: function () { // 方法
}
}
function fn () { // 函数
}
// 在里面的叫方法,在外面的叫函数。
- 函数和方法的不同点:
- 函数:函数是单独声明、单独存在的,并且调用的
函数名()
。 - 方法:方法在对象里面。调用的时候是
对象.方法
。
- 函数:函数是单独声明、单独存在的,并且调用的
利用new Object
来创建对象。
var obj = new Object(); // 创建了一个空的对象。
obj.uname = '张三丰'; //使用追加的方式来赋值。
obj.age = 18;
obj.sex = '男';
obj.sayHi = function () {
console.log('hi~')
}
console.log(boj.uname);
console.log(boj['sex']);
obj.sayHi();
// 我们是利用等号赋值的方法,添加对象的属性和方法。
// 每个属性和方法之间用分号结束。
// 调用跟第一种方法一模一样。
// new Object 的O要大写。
利用构造函数
来创建对象。
为什么需要用构造函数来创建对象?
-
就是因为我们前面两种创建对象的方式,一次只能创建一个对象。里面很多的属性和方法是大量相同的,我们只能复制。因此我们可以利用函数的方法,重复这些相同的代码,我们就把这个函数称为构造函数。
-
又因为这个函数不一样,里面封装的不是普通代码,而是对象。
-
构造函数:构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。就是把我们对象里面的一些相同的属性和方法抽象出来封装到函数里面。
需求:我们需要创建四大天王的对象。
相同的属性:名字、年龄、性别
相同的方法:唱歌
构造函数的语法格式:
function 构造函数名() {
this.属性 = 值;
this.方法 = function () {
}
}
new 构造函数名(); // 调用的时候一定要用new来进行调用。
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function (song) { //把’冰雨‘传给了song
console.log(song); // 把song打印出来了
}
}
var ldh = new Star('刘德华', 18, '男'); //调用函数返回的是一个对象。
console.log(typeof ldh); // object
console.log(ldh.name); // 刘德华
console.log(ldh.['age']); // 男 // 另外一种方法打印。
ldh.sing('冰雨');
var zxy = new Star('张学友', 19, '男');
console.log(zxy.name);
console.log(zxy.age);
// 1. 构造函数的名字首字母要大写。
// 2. 构造函数不需要return就可以返回结果。
// 3. 我们调用构造函数必须使用new。
// 4. 我们只要new 了一下Star() 调用函数就创建了一个对象,比如说ldh。
// 5. 我们的属性和方法前面必须添加 this。
构造函数和对象的区别
- 构造函数(泛指的某一大类,它类型与Java语言里面的类,抽象了对象的公共部分,封装到了函数里面。)
function Star (uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function (song) {
console.log(song);
}
}
- 对象(特指某一个具体的事物)
var ldh = new Star('刘德华', 18, '男'); // 调用函数返回的是一个对象
// 返回结果:{name: '刘德华', age: 18, sex: '男',sing: f}
- 我们利用构造函数创建对象的过程我们也称为对象的实例化。
new 关键字的执行过程
- new 构造函数可以在内存中创建了一个空的对象。
- this 就会指向刚才创建的空对象。
- 执行构造函数里面的代码,给这个空对象添加属性和方法。
- 返回这个新对象。(new 可以把这个值返回给这个对象,这就是为什么不需要返回值的原因。)
遍历对象
var obj = {
name: 'pink老师',
age: 18,
sex: '男'
}
console.log(obj.name);
console.log(obj.age);
console.log(obj.sex);
// 这样打印实在太麻烦
for … in 用于对数组和对象进行遍历。
for (var k in obj) {
console.log(k); // k 变量 输出,得到的是 属性名
console.log(obj[k]); // 得到的是里面的 属性值 必须要用中括号里面K。
}
注意:
我们使用 for…in 里面的变量,我们喜欢写 k 或者 key。
得到毫秒数的方法:
var date = new Date();
console.log(date.valueOf());
// 就是现在时间距离1970.1.1总的毫秒数。
var date = new Date();
console.log(date.getTime());
// 就是现在时间距离1970.1.1总的毫秒数。
- H5 新增的获得总的毫秒数。(有兼容性问题)
console.log(Date.now());
// 就是现在时间距离1970.1.1总的毫秒数。
- 简单的写法:(最常用的写法)
xxxxxxxxxx3 1var date = +new Date(); 2console.log(date);3// +new Date(); 返回的就是总的毫秒数。
注意: 这个毫秒数是永远不会重复的,江湖人称:“时间戳”。
创建数组的两种方式
- 利用数组字面量
var arr = [1, 2, 3];
console.log(arr[0]);
- 利用
new Array()
//var arr = new Array(); // 创建了一个空数组
// var arr = new Array(2); // 这个 2 表示 数组的长度为 2,里面有2个空的元素。
var arr = new Array(2, 3); // 等价于 [2,3] 这样写表示,里面有2个数组元素,是2和3
console.log(arr);
检测是否为数组
instanceof
运算符,它可以用来检测是否为数组
var arr = [];
console.log(arr.instanceof Array); // true
var obj = {};
console.log(arr.instanceof obj); // false
Array.isArray
(参数); (H5里面新增的方法,IE9以上才支持)
var arr = [];
console.log(Array.isArray(arr)); // true
但凡碰到img,就要设置宽和高。
JS 闪烁,可能是定时器没有清除好。
函数封装不会提高运行效率,但是会提高代码开发的效率和可维护的效率。
forEach();
本身就是一个局部作用域。
能用DOM0解决就用DOM0,DOM0解决不了的再用DOM2。
一个页面中有两个window.onload,只有后面那个生效。
对象的Boolean都是true。
null的Boolean为false。
点击事件的完成条件,鼠标在当前元素上按下,当前元素上抬起。
键盘上的按键都会有一个键码,获取键码是通过event事件对象的keyCode属性。
绑定键盘事件只能绑定给document。document.onkeydown = function () {};
判断全等的话,switch比if要方便得多。
只要事件委托
就一定会有target。
两种保存数值方式,一种是数组,一种是对象。有顺序用数组,没有顺序用对象。
-nodeName用的时候要注意,元素节点的nodeName要与标签名相同,而且要大写。
-nodeName用的时候要注意,属性节点的nodeName要与属性名相同,而且要小写。
[10, 80):10~80
中括号表示包含
,小括号表示不包含
。
p标签内不可以套p标签。如果你嵌套了,浏览器也会分开渲染解析,并且最后会多出来一对p标签。
本身是父子,浏览器直接解析为兄弟元素了。
定位会把元素提升一个层级,translate 也会把元素提升一个层级。
字符编码:按照某种规则翻译成机器可读的文字。
父子一般用padding(给父级设置padding),兄弟一般用margin。
牵涉到左右布局,浮动时要设置宽度。
过渡动画的触发条件:只要是能过渡的样式改变就能触发。如:hover,onclick,点击改变类名。
判断null类型和undefined类型:全等。
最大进制(36进制),26个字母
+ 0~9
。
0进制的3为3,0进制转换时默认为10。
科学计数法:
12E23: 12x10的23次方。
三元运算符:?:;
三元运算符是有返回值的。
var b = 0;
b = a === 1?2:3;
b = 2;
缓存利用:
- 服务器的内容是否被修改,客户端需要向服务区核查。
- 每一个文件都有一个唯一的标识ID去判断是否一致,并且客户端和服务器文件的修改时间是否一致。
continue在while循环里会直接退出,continue在for里会停止当次循环,继续执行下面的代码。
迭代:遍历。
迭代语句:遍历语句。
对象和数组的本质:存数据。
清空数组:
- 等于一个空数组。(改变原数组)
- 设置length的长度为0。(不改变原数组)
数组遍历方法:forEach、map、some、every
var obj = {};
obj.toString(); // "[object Object]"
// "[object Object]" object 指这是一个对象,Object指这是一个对象类型。
变量分为两种:
- 变量保存的是值。(基本类型的变量)
- 变量保存的是地址。(引用类型的变量)
数据分为两种:
- 基本类型
- 对象类型
释放内存:局部(自动释放)、全局(手动释放)。
对象:
- 储存数据的一种数据结构
{}
。 - 显示事物在编程中的一个抽象。
小括号的作用:
- 提升优先级
- 函数调用
每一个函数都一个call()
和 apply()
方法。
call、apply、bind是function原型对象上的方法。
只要是函数都会有这个三个方法。
call 的返回值就是被调用函数的返回值。
bind返回一个函数。
只要是默认调用,this肯定指向window。
计时器的this指向window。
函数不调用,会隐式丢失。
每个函数都有一个prototype属性,他默认指向一个Object空对象(即称为:原型对象)。只有函数才拥有prototype属性。
显式原型:我们可以直接访问、操作、修改。
所有的函数都是function对象实例化出来的。
function Function() {}
这个function构造函数是被它自己实例化出来的。(function构造函数就是它自己的构造函数)。
弹幕是用构造函数来写的。弹幕从右边生成,左边删除。
构造函数没有原型链,只有对象才有原型链。
用新对象替换prototype属性,不会更改以前的实例。
__proto__
属性,它是对象所独有的。prototype
是函数所独有的。
实例:使用new操作符 创建一个实实在在的对象。
实例化:使用new创建一个对象函数的过程。
函数有两个身份:1. 显式原型(函数)。2. 隐式原型(对象),对象可以扩展属性和方法。
函数定义声明的时候就有作用域(是静态的),函数调用的时候才有执行上下文(是动态的)。
a.b
先从函数作用域中查找a是否能找到,如果不能找到会直接报错。
如果找到了,那么再在a原型链里面查找b。
构造函数的this指向 其 实例化对象
。
构造函数如果return一个object类型值,则不再返回实例化对象,如果return的是一个基本类型的值,则不影响返回实例化对象。
构造函数中,this就是指向实例化对象。
面向对象三大特征:封装、继承、多态。
JS继承:你想要子类继承父类,你需要自己写。
最通用的继承方式是:构造函数+原型
的组合继承。
线程是进程里面的一个独立单元。一个进程里面可能有一个或多个线程。通常认为一个进程就是打开一个软件。
JS 就是典型的单线程语言(缺点就是效率低。)。虽然js是单线程,但是它有一个好队友,Google浏览器是多线程的(现在浏览器基本都是多线程的)。
所有的代码都要在JS上执行,但是浏览器可以帮忙处理一些事情。
worker.js
是操作不了DOM的,因为它没有DOM,它只是一个js文件。
src属性是可以跨域的。
-
节流:在一段时间内只触发第一次。
-
防抖:在一段时间内只触发最后一次。
css
中的calc
是calculate
的缩写。
var arr = [10]; // 创建一个下标为0,值为10的数组。
var arr = new Array(10); // 创建一个下标从0-10的空数组。
null 和 undefined 不能有属性,否则会报错。
arguments 中有一个属性 callee,这个属性对应一个函数对象,就是当前正在执行的函数对象。
function fn(a, b){
}
fn(1, 2);
console.log(arguments.callee); // 当前对象
console.log(callee === fn) // true
Math 不是一个构造函数。
它属于一个工具类,不用创建对象。它里面封装了数学类的属性和方法。我们可以直接使用。
如:Math.abs();
监听浏览器中整个页面的滚动事件
js原生:window.onscroll
jquery:$(window).scroll()
js修改元素的样式
固定语法:元素.style.样式名 = “样式值(如果是数值如:px,需要带单位)”
js读取元素的样式
固定语法:元素.style.样式名
通过style读取到的都是内联(行内)样式,无法读取样式表里的样式。
获取元素当前显示的样式
语法:元素.currentStyle.样式名
它可以读取当前元素正在显示的样式。
如果当前元素没有设置要获取的样式,则获取默认值。
这个currentStyle只有IE支持,其他的浏览器都不支持。
在其他浏览器中,我们可以使用 getComputedStyle()
这个方法来获取元素当前的样式,这个方法IE9以上的浏览器都支持,其他浏览器也都支持。
这个方法是window的方法可以直接使用。
getComputedStyle()
需要两个参数:
第一个:要获取样式的元素
第二个:可以传递一个伪元素(一般都传null)
该方法会返回一个对象,对象总封装了当前元素对应的样式。
如:
var obj = getComputedsStyle(box1, null);
console.log(obj.width);
// 或写成:
console.log(getComputedsStyle(box1, null).width);
定义一个函数,用来获取指定元素的当前的样式。参数:
obj 要获取样式的元素
name 要获取的样式名
function getStyle(obj, name) {
return window.getComputedStyle?getComputedStyle(obj, null)[name] : obj.currentStyle[name];
}
注意:通过currentStyle和getComputedStyle()读取到的样式都是只读的,不能修改。如果要修改必须使用style。
${}可以写js表达式(只要有返回值的就是js表达式):变量、常量、字面量([], {})、函数、函数调用、三元运算、与或非、其他运算)。
注意:for/while/do…while/if/switch 这个不是表达式,而是语句。
变量分为两种:
- 变量保存的是值。(基本类型的变量)
- 变量保存的是地址。(引用类型的变量)
数据分为两种:
- 基本类型
- 对象类型
释放内存:局部(自动释放)、全局(手动释放)。
对象:
- 储存数据的一种数据结构
{}
。 - 显示事物在编程中的一个抽象。
小括号的作用:
- 提升优先级
- 函数调用
每一个函数都一个call()
和 apply()
方法。
只要是默认调用,this肯定指向window。
计时器的this指向window。
函数不调用,会隐式丢失。
函数的返回值 return:
返回要用return,return后面的值是返回值,这个值将会返回到函数的调用处。
函数从哪里调用返回的结果就会返回到哪里去。
什么时候使用return,什么时候不用return完全看你的函数的功能:
- 函数只是实现某功能,最终结果需要返回给函数的调用者 函数名(),通过return实现。
- 只要函数遇到return就会把后面的结果返回给函数的调用者,函数名() = return 后面的结果。
setTimeout 只执行一次,setInterval如果你不停止就会一直执行。
设置计时器是同步的,调用计时器是异步的。
事件绑定后,只要不取消就会一直存在。
计时器的this指向的是window。
函数有两个身份:1. 函数(函数都有显示原型) 2. 对象(对象都有隐式原型)。
原型链是按照隐式原型一级一级来走的。
只有构造函数才能真正使用prototype原型对象。只有函数被实例化以后prototype才会有用,不然prototype没有意义。
设置对象的时候不会走原型链,获取对象的时候会根据原型链的规则查找。
什么是数据?
存储在内存中代表特定信息的东西,本质上是010101…
什么是内存?
内存条通电后产生的可储存数据的空间(临时的)。
内存产生和死亡:内存条(电路板) → 通电 → 产生内存空间 → 存储数据 → 处理数据 → 断电 → 内存空间和数据都消失
一块小内存的两个数据:
- 内部存储的数据。
- 地址值的数据。
什么是变量?
-
可变化的量,由变量名和变量值组成
-
每个变量都定义一块小内存,变量名用来查找对应的内存,变量值就是内存中保存的数据。
什么是常量?不可变化的量。
递归:
- 找规律
- 找出口(没有出口会死循环)
每一个函数都有一个name属性
funtion test() {}
console.log(test.name) // test
未完待续。。。。。。