目录
一、HTML+CSS
1. 如何理解HTML的语义化
2. 从浏览器地址栏输入url回车会发生什么
3. 溢出的文字显示省略号
4. css选择器和优先级
css选择器
5. BFC
6. 水平垂直居中的方法
二、JavaScript
1. 基本数据类型
2. 数组的使用
一、数组序列化
二、栈和队列方法
三、排列方法
四、操作方法
五、位置方法
六、迭代方法
2.1 利用函数求任意个数的最大值
2.2 利用函数翻转任意数组 reverse 翻转
2.3 利用函数冒泡排序 sort 排序
2.4 利用函数判断闰年
2.5 利用函数判断闰年
2.6 利用set方法数组去重
3. 作用域和作用域链
3.1 预解析
三、ES6新特性
1. let和const关键字
2. 原型和原型链
3. 模板字符串
4. 扩展运算符
5. 箭头函数
6. 解构赋值
7. Symbol
8. Promise
9. 类的实例属性
10. new关键字
后续更新中....
先强制一行显示`white-space:noweap
超出的部分隐藏`overflow:hidden
超出的部分用省略号显示`text-overflow:ellipsis
overflow:hidden;
text-overflow:ellipsis;
display: -webkit-box;弹性伸缩盒子模型显示
-webkit-line-clamp:2;//限制在一个块元素显示的文本行数
-webkit-box-orient:vertical;//设置或检索伸缩对象子元素排序
大家都知道样式的优先级一般为 !important > style > id > class
选择器 | 示例 |
|类型选择器 | h1 { } |
通配符选择器 | * { } |
类选择器 | .box { } |
ID选择器 | #unique { } |
标签属性选择器 | a[title] { } |
伪类选择器 | p:first-child { } |
伪类选择器 | p::first-line { } |
后代选择器 | article p |
子代选择器 | article > p |
相邻兄弟选择器 | h1 + p |
通用兄弟选择器选择器 | h1 ~ p |
BFC 即块级格式上下文,这是一个独立渲染的区域,规定了内部如何布局,并且这个区域的子元素不会影响到外面的元素,其中比较重要的布局规则有内部box垂直放置,计算BFC高度的时候,浮动元素也参与计算。
BFC 具有一些特性:
创建 BFC 的方式:
1. 利用绝对定位,设置 `left: 50%` 和 `top: 50%` 现将子元素左上角移到父元素中心位置,然后再通过 `translate` 来调整子元素的中心点到父元素的中心。
2. 利用绝对定位,子元素所有方向都为 `0` ,将 `margin` 设置为 `auto` ,由于宽高固定,对应方向实现平分,该方法必须**盒子有宽高**。
3. 利用绝对定位,设置 `left: 50%` 和 `top: 50%` 现将子元素左上角移到父元素中心位置,然后再通过 `margin-left` 和 `margin-top` 以子元素自己的一半宽高进行负值赋值。该方法**必须定宽高**。
在 JS 中共有 8 种基础的数据类型,分别为: `Undefined` 、 `Null` 、 `Boolean` 、 `Number` 、 `String` 、 `Object` 、 `Symbol`(ES6新增,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。) 、 `BigInt`(表示任意大小的整数)。
1.1 值类型和引用型数据的理解
1.2 数据类型的判断
typeof:能判断所有值类型,函数。不可以对 null、对象、数组 进行精确判断,因为都返回 `object` 。
console.log(typeof undefined); // undefined
console.log(typeof 2); // number
console.log(typeof true); // boolean
console.log(typeof "str"); // string
console.log(typeof Symbol("foo")); // symbol
console.log(typeof 2172141653n); // bigint
console.log(typeof function () {}); // function
// 不能判别
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof null); // object
instanceof:能判断**对象**类型,不能判断基本数据类型,其内部运行机制是判断在其原型链中能否找到该类型的原型。
Object.prototype.toString.call():所有原始数据类型都是能判断的,还有 **Error 对象,Date 对象**等。
Object.prototype.toString.call(2); // "[object Number]"
Object.prototype.toString.call(""); // "[object String]"
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(Math); // "[object Math]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(function () {}); // "[object Function]"
1.3 如何判断数组
Array.isArray(arr); // true
arr.__proto__ === Array.prototype; // true
arr instanceof Array; // true
Object.prototype.toString.call(arr); // "[object Array]"
数组API
var arr = [1,5,2,8,10,{a:1}];
console.log(arr);//[ 1, 5, 2, 8, 10, { a: 1 } ]
console.log(arr.toString());//”1,5,2,8,10,[object Object]”
console.log(arr.join(""));//”152810[object Object]”
console.log(arr.join("-"));//”1-5-2-8-10-[object Object]”
// 1. 翻转数组
var arr = ['pink', 'red', 'blue'];
arr.reverse();
console.log(arr);
// 2. 数组排序(冒泡排序)
var arr1 = [13, 4, 77, 1, 7];
arr1.sort(function(a, b) {
// return a - b; 升序的顺序排列
return b - a; // 降序的顺序排列
});
console.log(arr1);
var str = 'andy';
console.log(str.concat('red'));//andyred
// 2. substr('截取的起始位置', '截取几个字符');
var str1 = '改革春风吹满地';
console.log(str1.substr(2, 2)); // 春风
var arr = ['red', 'green', 'pink'];
console.log(arr.indexOf('blue'));//-1
// 返回数组元素索引号方法 lastIndexOf(数组元素) 作用就是返回该数组元素的索引号 从后面开始查找
var arr = ['red', 'green', 'blue', 'pink', 'blue'];
console.log(arr.lastIndexOf('blue')); // 4
用indexOf()实现数组去重
function unique(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i]);
}
}
return newArr;
}
var demo = unique(['blue', 'green', 'blue'])
console.log(demo);
function getMax() {
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
console.log(getMax(1, 2, 3));
function reverse(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
return newArr;
}
var arr1 = reverse([1, 3, 4, 6, 9]);
console.log(arr1);
var arr2 = reverse(['red', 'pink', 'blue']);
console.log(arr2);
function sort(arr) {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
var arr1 = sort([1, 4, 2, 9]);
console.log(arr1);
function isRunYear(year) {
// 如果是闰年我们返回 true 否则 返回 false
var flag = false;
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
console.log(isRunYear(2000));
function backDay() {
var year = prompt('请您输入年份:');
if (isRunYear(year)) { // 调用函数需要加小括号
alert('当前年份是闰年2月份有29天');
} else {
alert('当前年份是平年2月份有28天');
}
}
backDay();
// 判断是否为闰年的函数
function isRunYear(year) {
// 如果是闰年我们返回 true 否则 返回 false
var flag = false;
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
function unique(arr){
var arr2 = arr.sort();
var res = [arr2[0]];
for(var i=1;i
作用域 :就是代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突
作用域链 : 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链 **就近原则**
案例:
// 案例1 : 结果是几?
function f1() {
var num = 123;
function f2() {
var num = 0;
console.log(num); //num=0 站在目标出发,一层一层的往外查找
}
f2();
}
var num = 456;
f1();
// 案例2 :结果是几?
var a = 1;
function fn1() {
var a = 2;
var b = '22';
fn2();
function fn2() {
var a = 3;
fn3();
function fn3() {
var a = 4;
console.log(a); //a=4
console.log(b); //b=22
}
}
}
fn1();
1. 我们js引擎运行js 分为**预解析、代码执行**
- 预解析 js引擎会把js 里面所有的 var 还有 function 提升到当前作用域的最前面
- 代码执行 按照代码书写的顺序从上往下执行
2. 预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
- **变量提升**就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作
- **函数提升**就是把所有的函数声明提升到当前作用域的最前面 不调用函数
案例:
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
// 相当于执行了以下操作
var num;
function fun() {
var num;
console.log(num);
num = 20;
}
num = 10;
fun();
// // 案例2
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
// // 相当于以下代码
var num;
function fn() {
var num;
console.log(num);
num = 20;
console.log(num);
}
num = 10;
fn();
// // 案例3
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
// 相当于以下代码
var a;
function f1() {
var b;
var a;
b = 9;
console.log(a);
console.log(b);
a = '123';
}
a = 18;
f1();
// 案例4
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
// 以下代码
function f1() {
var a;
a = b = c = 9;
// 相当于 var a = 9; b = 9; c = 9; b 和 c 直接赋值 没有var 声明 当 全局变量看
// 集体声明 var a = 9, b = 9, c = 9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);
区别:let表示声明变量,而const表示声明常量,两者都为块级作用域;const 声明的变量都会被认为是常量,意思就是它的值被设置完成后就不能再修改了。
需要注意:
- let 关键词声明的变量不具备变量提升(hoisting)特性
- let 和 const 声明只在最靠近的一个块中(花括号内)有效
- 当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING
- const 在声明时必须被赋值
一般情况下,我们的公共属性定义到构造函数里面, 公共的方法我们放到原型对象身上
如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定;ES6反引号 **` `` `** 直接搞定;
$("body").html(`This demonstrates the output of HTML content to the page,
including student's ${name}, ${seatNumber}, ${sex} and so on.`);0
let ary = ["a", "b", "c"];
console.log(...ary)//a,b,c
let ary1 = [1, 2, 3];
let ary2 = [4, 5, 6];
let ary3 = [...ary1, ...ary2];
console.log(ary3)// [1, 2, 3, 4, 5, 6]
//合并数组的第二种方法
let ary1 = [1, 2, 3];
let ary2 = [4, 5, 6];
ary1.push(...ary2);
console.log(ary1)// [1, 2, 3, 4, 5, 6]
var oDivs = document.getElementsByTagName('div');
console.log(oDivs)
var ary = [...oDivs];
ary.push('a');
console.log(ary);
按照一定模式从数组或对象中提取值,然后对变量进行赋值(先提取,再赋值)
// 对象
const student = {
name: 'Sam',
age: 22,
sex: '男'
}
// 数组
// const student = ['Sam', 22, '男'];
// ES5;
const name = student.name;
const age = student.age;
const sex = student.sex;
console.log(name + ' --- ' + age + ' --- ' + sex);
// ES6
const { name, age, sex } = student;
console.log(name + ' --- ' + age + ' --- ' + sex);
唯一标识,symbol作为对象的属性名时不会被`for...in`,`for...of`,`Object.keys()`识别;可以改用`Reflect.ownkeys`方法.
是一部编程的解决方案,状态不受外界影响
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 1000)
}).then(res => {})
.catch(err => {})
```
#### 9.Class类
```
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
其中:
1. constructor方法是类的默认方法,通过new 命令生成对象时会调用该方法,如果声明类时没有定义constructor,会默认定义一个空的。
1. 生成实例时必须用new ,不用会报错
1. 不存在变里提升(选定义类,再new实例)
类的静态方法:
所有在类中定义的方法都会被实例继承,如果不想被继承,可以在定义时加上static。表示为静态方法。
class Foo {
static match() {}
}
Foo.match()
const f = new Foo()
f.match() // 报错
类的方法默认被实例继承,那么属性呢?也是继承的,写法如下:
class Foo {
myProp = 111;
...
}
classr的继承 extends
class Point {}
class PointSon extends Point {
constructor(x, y, z) {
super(x, y)
this.z = z
}
}
其中:
1. super等同于父类的constructor。
1. 子类必须在constructor中调用super, 也就是说用extends去继承一个类,就必须调用这个类(父类)的constructor。是因为子类没有自己的this对象,而是继承父类的this,然后对其进行加工
1. 如果了类没有写constructor,会默认生成一个,并包含了super(...args)
5.1 new关键字执行过程
1. new 构造函数可以在内存中创建了一个空的对象
2. this 就会指向刚才创建的空对象
3. 执行构造函数里面的代码 给这个空对象添加属性和方法
4. 返回这个对象