目录
先强制一行显示`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<arr2.length;i++){
if(arr2[i] !== res[res.length-1]){
res.push(arr2[i]);
}
}
return res;
}
//利用下标查询
function unique(arr){
var newArr = [arr[0]];
for(var i=1;i<arr.length;i++){
if(newArr.indexOf(arr[i]) == -1){
newArr.push(arr[i]);
}
}
return newArr;
}
作用域 :就是代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突
作用域链 : 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链 **就近原则**
案例:
// 案例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. 返回这个对象