之后需要自己梳理的/有疑问的
CSS
盒子模型 (梳理) ? width和height:内容的宽度、高度(不是盒子的宽度、高度)。 ? padding:内边距。 ? border:边框。 ? margin:外边距。
流动float
JavaScript
Web前端有三层:
HTML:从语义的角度,描述页面结构
CSS:从审美的角度,描述样式(美化页面)
JavaScript:从交互的角度,描述行为(实现业务逻辑和页面控制)
JavaScript基础分为三个部分:
ECMAScript:JavaScript 的语法标准。包括变量、表达式、运算符、函数、if语句、for语句等。
DOM:Document Object Model(文档对象模型),操作页面上的元素的API。比如让盒子移动、变色、改变大小、轮播图等等。
BOM:Browser Object Model(浏览器对象模型),操作浏览器部分功能的API。通过BOM可以操作浏览器窗口,比如弹框、控制浏览器跳转、获取浏览器分辨率等等。
通俗理解就是:ECMAScript 是 JS 的语法;DOM 和 BOM 浏览器运行环境为 JS提供的API。
JS有如下特点
- JS是一种解释性语言:不需要先编译
- 单线程
- ECMAScript标准 最新为ES6
怎么写JavaScript
<input type="button" value="点我" onclick="alert('方法1')" />
上面的onclick即为JS代码
<body>
<script type="text/javascript">
alert('方式2');
console.log('方式2');
</script>
</body>
像CSS一样,用<script> 标签表明
<script src="tool.js"></script>
引入外部的js文件
JS语法规则
(1)JavaScript对换行、缩进、空格不敏感。每一条语句以分号结尾。
<script type="text/javascript">
alert("您好");
alert("hihi");
</script>
(2)所有的符号,都是英语的。比如括号、引号、分号。
(3)严格区分大小写。
常用语句
alert() console.log() prompt()
变量
字面量
变量
用var 来声明
var a=100;
弱类型语言
var name='qianguyihao'
不需要声明数据类型
基本数据类型(值类型):String 字符串、Number 数值、Boolean 布尔值、Null 空值、Undefined 未定义。
引用数据类型(引用类型):Object 对象。
运算符
运算符 描述 + 加、字符串连接 - 减 * 乘 / 除 % 获取余数(取余、取模)
自增++ 自减–
a++和++a都让值增加1
区别在于,a++的值已经给了a,++a则先自增,再将值赋给表达式
一元运算符
typeof 类型 + 正数 - 负数
逻辑运算符
&& 与 || 或 ! 非
赋值运算符
= += -= *= /= %=
比较运算符
> 大于号 < 小于号 >= 大于或等于 <= 小于或等于 == 等于 === 全等于 != 不等于 !== 不全等于
三元运算符
条件表达式 ? 语句1 : 语句2;
条件运算符在执行时,首先对条件表达式进行求值:
如果该值为true,则执行语句1,并返回执行结果
如果该值为false,则执行语句2,并返回执行结果
流程控制语句
顺序结构
选择结构:if 语句、switch 语句
循环结构:while 语句、for 语句
if (条件1){
}else if{
}else{
}
示例
var bianhao = parseInt(prompt("您加92或97?"));
var sheng = parseFloat(prompt("加多少升?"));
if (bianhao == 92){
if (sheng < 20){
var price = sheng * 6;
}else{
var price = sheng * 5.9;
}
}else if (bianhao == 97){
if (sheng < 30){
var price = sheng * 7;
}else {
var price = sheng * 6.95;
}
}
alert("价格是"+price)
switch语句写法和c一样
switch(表达式){
case 值1:
句1;
break;
case 值2:
break;
...
...
default:
句n+1;
break
}
循环语句
for和while 示例
for (var i = 1;i <= 100;i = i + 4){
console.log(i);
}
while(条件){
语句
}
do{
语句
}while(条件)
while和do while的区别在于先判断还是后判断
循环语句可以使用label来进行标记
outer: for (var i = 0; i < 5; i++) {
console.log('外层循环 i 的值:' + i);
for (var j = 0; j < 5; j++) {
break outer;
console.log('内层循环 j 的值:' + j);
}
}
此时break跳出的是外层循环而非内层
continue同理
对象
var obj = new Object();
obj.sayName = function () {
console.log('smyhvae');
};
console.log(obj.sayName);
console.log('-----------');
console.log(obj.sayName());
和python比较类似
分类 1.内置对象:
由ES标准中定义的对象,在任何的ES的实现中都可以使用
比如:Object、Math、Date、String、Array、Number、Boolean、Function等。
2.宿主对象:
由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象。
比如 BOM DOM。比如console、document。
3.自定义对象:
由开发人员自己创建的对象 通过 new 关键字创建出来的对象实例,都是属于对象类型,比如Object、Array、Date等。
基本包装类
JS 为我们提供了三个基本包装类:
String():将基本数据类型字符串,转换为 String 对象。
Number():将基本数据类型的数字,转换为 Number 对象。
Boolean():将基本数据类型的布尔值,转换为 Boolean 对象。
数组
Array
构造方式1
var arr1 = [];
var arr1 = [1,2,3];
构造方式2
var arr = new Array(参数)
函数
function 函数名(参数1,参数2...){
语句...
}
var fun2 = function(){
语句...
}
注意,上面的fun2只是变量名
作用域
概念:通俗来讲,作用域是一个变量或函数的作用范围。作用域在函数定义时,就已经确定了。
目的:为了提高程序的可靠性,同时减少命名冲突。
函数内作用域的变量,外部无法访问,即全局/局部变量的概念
变量/函数声明提前
使用var function声明的变量/函数 会被声明提前
使用var创建的函数不会被提前
在函数的作用域中,var声明的变量也会提前
执行期上下文
当函数执行时(准确来说,是在函数发生预编译的前一刻),会创建一个执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境。
每调用一次函数,就会创建一个新的上下文对象,他们之间是相互独立且独一无二的。当函数执行完毕,它所产生的执行期上下文会被销毁。
this
解析器在调用函数每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就是 this,this 指向的是一个对象,这个对象我们称为函数执行的 上下文对象。
1.以函数的形式(包括普通函数、定时器函数、立即执行函数)调用时,this 的指向永远都是 window。比如fun();相当于window.fun();
2.以方法的形式调用时,this 指向调用方法的那个对象
3.以构造函数的形式调用时,this 指向实例对象
4.以事件绑定函数的形式调用时,this 指向绑定事件的对象
5.使用 call 和 apply 调用时,this 指向指定的那个对象
闭包
闭包(closure):指有权访问另一个函数作用域中变量的函数。
function fn1() {
let a = 10;
function fn2() {
console.log(a);
}
fn2();
}
fn1();
fn2调用了fn1的变量 a
对象创建方法
const obj1 = {
name: 'hihi',
age: 28,
};
const obj2 = {
name: "hihi",
age: 26,
isBoy: true,
test: {
id: 123,
tel: 180
}
sayName: function() {
console.log(this.name);
}
};
console.log(JSON.stringify(obj));
工厂模式
function createPerson(name, age, gender) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function () {
alert(this.name);
};
return obj;
}
var obj2 = createPerson('一号', 28, '男');
var obj3 = createPerson('二号', 16, '女');
var obj4 = createPerson('三号', 18, '女');
使用构造函数
var stu1 = new Student('smyh');
console.log(stu1);
stu1.sayHi();
var stu2 = new Student('vae');
console.log(stu2);
stu2.sayHi();
function Student(name) {
this.name = name;
this.sayHi = function () {
console.log(this.name + '厉害了');
};
}
构造函数和普通函数的区别 构造函数的创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写。
构造函数和普通函数的区别就是调用方式的不同:普通函数是直接调用,而构造函数需要使用 new 关键字来调用。
this 的指向也有所不同:
1.以函数的形式调用时,this 永远都是 window。比如fun();相当于window.fun();
2.以方法的形式调用时,this 是调用方法的那个对象
3.以构造函数的形式调用时,this 是新创建的实例对象
拷贝
浅拷贝:只拷贝最外面一层的数据;更深层次的对象,只拷贝引用。
深拷贝:拷贝多层数据;每一层级别的数据都会拷贝。
推荐使用 Object.assgin()
obj2 = Object.assgin(obj2, obj1);
Object.assign(目标对象, 源对象1, 源对象2...);
注意,该方式中,相同则覆盖,不同则追加
深拷贝实现方式:递归
let obj1 = {
name: 'hihi',
age: 28,
info: {
desc: 'hello',
},
color: ['red', 'blue', 'green'],
};
let obj2 = {};
deepCopy(obj2, obj1);
console.log(obj2);
obj1.info.desc = 'github';
console.log(obj2);
function deepCopy(newObj, oldObj) {
for (let key in oldObj) {
let item = oldObj[key];
if (item instanceof Array) {
newObj[key] = [];
deepCopy(newObj[key], item);
} else if (item instanceof Object) {
newObj[key] = {};
deepCopy(newObj[key], item);
} else {
newObj[key] = item;
}
}
}
|