判断
回到题目,如果你真想检验一个人的水平。第一步先考察一下基本的编程基础,问几个基本的编程问题,可以和前端相关也可以无关。比如垃圾收集大致是怎么做的,setTimeout 大致做了什么(说会在另一个线程里执行回调的直接毙掉)。
第二步考察一下知识面,问问http、tcp的基本知识,dns是怎么工作的,或者常用框架的实现原理,看看候选人是不是除了自己的一亩三分地什么都不关心。
第三步考察hold业务逻辑的能力,从一个简单的注册页,或者查询页开始,先让说下代码的基本架构,然后需求、性能、可靠性、安全层层加码,看看能不能很快的反馈出解决方案。能对答如流的要么做过,要么对他来说这种复杂度的东西是小case。
前三步都没问题,基本上说明候选人已经还行了,但是行到什么程度,不知道。如果想找比较厉害的,就增加个第四步,亮点项目考察。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
总的来说,面试官要是考察思路就会从你实际做过的项目入手,考察你实际编码能力,就会让你在电脑敲代码,看你用什么编辑器、插件、编码习惯等。所以我们在回答面试官问题时,有一个清晰的逻辑思路,清楚知道自己在和面试官说项目说技术时的话就好了,我整理一套前端面试题分享给大家,希望对即将去面试的小伙伴们有帮助!
name : “张三”,
age : 18,
eat : function () {
console.log(“爱吃KFC”)
}
}
for (var p in person){
console.log(p,“值:”+person[p])
}
小结:遍历对象时使用中括号的方式,因为不知道对象中的变量究竟是属性还是方法,所以使用中括号更加灵活。
6、JavaScript运算符
运算符:加、减、乘、除、赋值、取余(也称求余)、自增、自减
例如:定义了变量,却没有赋值,输出就是undefined
var a;
赋值:=
求余:%
自增:++
自减:–
取余的意思是:一个数字除以另一个数字,除不尽的部分就是余数
例如:5除以2 余数为1
自增分为前置++和后置++,自减也同理
关于自增和自减的一个练习:
var a = 1;
var b;
var sum = (b = a++±-a) + a-- + b++;
答案:5 拆分理解:sum = ( b = 1 + 1) + 1 + 2
7、数组
数组是一个容器,可以存放一个或者多个对象。
创建数组的四种方式:
1、直接量定义数组:使用一对中括号声明一个数组对象,在定义的时候直接对数组进行初始化 (常用)
var arr = [“apple”,“banana”,“orange”];
console.log(arr)
2、采用构造函数:new Array(); 这里是直接创建一个空的数组
var arr = new Array();
arr.push(“aaa”)
arr.push(“bbb”)
console.log(arr)
3、采用构造函数:创建的时候设置初始长度
var arr = new Array(5);
arr[0]=“张三” // 对数组进行赋值
arr[1]=“李四”
console.log(arr) // [‘张三’, ‘李四’, empty × 3]
console.log(arr.length) // 5
4、采用构造函数:创建的时候赋予元素
var arr = new Array(“比亚迪”,“宝马”,“奔驰”,“大众”);
console.log(arr)
数组方法:
push方法:在数组的尾部添加新元素
删除:splice 或 pop
pop方法:删除数组的最后一个元素
splice方法:可插入、删除、替换数组元素 (在原有的数组上进行修改)
splice用前俩个参数进行定位,余下的参数表示插入部分
参数1:数组的下标位置
参数2:要删除元素的个数
示例:
var nums = [1,2,3,4,5];
nums.splice(2,1); // 删除 3 号元素
console.log(nums) // [1, 2, 4, 5]
演示splice的插入元素:
var nums = [1,2,3,4,5];
nums.splice(2,1,38,66); // 把3替换为 38 在38后面添加一个元素 66
console.log(nums) // [1, 2, 38, 66, 4, 5]
元素转字符串:join方法
join是把所有元素放入一个字符串,元素是通过指定分隔符进行分隔的
var str = nums.join(“,”); // 也可以使用其他的 – 555 等等进行分隔
console.log(str) // 1,2,38,66,4,5
拓展:数组的其他方法
concat方法:
将俩个数组或者元素之间连接起来,调用该方法的数组放在前面,方法实参放在后面
var arr1=[1,2,3]
var arr2=[4,5,6]
var arr3 = arr1.concat(arr2)
console.log(arr3) // [1, 2, 3, 4, 5, 6]
pop方法的补充:删除数组中的最后一个元素,切会将这个被删除的元素返回
var del1 = arr3.pop()
console.log(“被删除的元素是:”+del1) // 6
reverse方法:将数组的顺序反转
var arr4 = arr3.reverse()
console.log(arr4) // [6, 5, 4, 3, 2, 1]
shift方法:删除数组的第一项,并返回删除元素的值(和pop进行对比学习)
arr4.shift()
unshift方法:将元素添加到数组开头,并返回数组的长度(和push进行对比学习)
arr4.unshift(115)
slice方法:截取数组的元素,左闭右开(只有一个参数的时候,从当前位置到最后一个元素)
console.log(arr4) // [115, 118, 4, 3, 2, 1]
console.log(“截取数组”)
var arr5 = arr4.slice(1,3) // 118,4
var arr6 = arr4.slice(1) // [118, 4, 3, 2, 1]
map方法:映射—指数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
var arr7 = [1,2,3,4,5];
var arr8=arr7.map(function (x) {
return x*0.9;
})
console.log(arr8) // [0.9, 1.8, 2.7, 3.6, 4.5]
filter方法:过滤—数组中的每一项运行给定函数,返回满足过滤条件组成的数组。
var arr9=arr7.filter(function (x,index) {
return x%3==0 || index>3;
})
console.log(arr9) // 3,5
foreach方法:对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值。
参数都是function类型,默认有传参,参数分别为:
遍历的数组内容
第对应的数组索引
数组本身
arr7.forEach(function (x,index,arr) {
console.log(x+’ | ‘+index+’\t’+arr) // 1 | 0 1,2,3,4,5 一直到 5 | 4 1,2,3,4,5
})
every方法:判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true。
var arr10=arr7.every(function (x) {
return x<10;
})
console.log(arr10) // true
some方法:判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。
var arr11=arr7.some(function (x) {
return x<2;
})
console.log(arr11) // true
8、函数七重关
一、函数定义
第一种方式:使用function关键字,后面是方法名,然后函数体
// 定义函数
function test1() { // 函数体
document.write(“My Page”)
}
test1(); // 调用函数
第二种方式:定义一个变量,把函数赋值给变量
var fun1=function () {
console.log(“定义函数的另一种方式”)
}
fun1()
区别:第二种方式必须先定义后调用
JavaScript编译原理
var a = 10;
JavaScript代码在运行之前会经过一个编译的过程,而编译有三个步骤。
1、分词
分词的目的是把这些代码分解为一个个代码块
比如刚才的例子,如果经过分词的步骤,那么得到的结果就是var、a、=、2、;。
2、解析
由JavaScript编译器对刚才分词得到的一个个 代码块进行解析,生成一棵抽象的语法树(AST)。
抽象语法树定义了代码本身,通过操作这棵树可以精准地定位到 赋值语句、声明语句和运算语句。
抽象语法树的创建可以在此网站自行调试和验证。https://esprima.org/demo/parse.html
3、代码生成
JavaScript引擎会把在第二个步骤中生成的抽象语法树进行转换,转换成 什么呢?没错,就是可执行的代码。
二、作用域
作用域:
全局作用域
函数作用域
作用域:就是当你要查找某一个变量的时候,你可以在什么范围呢找到这个变量。这个寻找的范围就是作用域。
不论是全局作用域还是函数作用域,都被定义在词法阶段。
词法阶段就是JavaScript代码编译的第一个步骤–分词。
全局作用域包着一个函数作用域,在函数作用域里面可以访问全局作用域里面的变量。但是反过来的话,全局作用域想要
调用函数作用域中定义的变量却是不可以的。
因此:当发生作用域嵌套的时候,只能里面的访问外面的。
示例:
var five = “星期五”
function five1() {
console.log(“全局变量:”+five)
}
five1()
但是下面这种形式就不是作用域嵌套,因为变量没有定义在函数体中
if(true){
var six = “星期六”
}
console.log(“测试if中的变量:”+six) // 测试if中的变量:星期六
这里并没有出现函数,所以不算作用域嵌套。
if(false){
var seven = “星期六”
}
console.log(“测试if中的变量:”+seven) // 测试if中的变量:undefined
这里undefined是因为代码在分词阶段和解析阶段,变量seven依然会被获取,系统默认给undefined值。
又因为变量seven没有在某一个函数体中,而是在全局作用域中,所以console.log方法可以访问这个变量。
加深理解:
var a = 1;
function test() {
var a;
var inner = function () {
console.log(a) // undefined
}
inner();
}
test();
解析:函数作用域里面嵌套了函数作用域,那么在最里面的inner函数中访问一个变量,就会优先在inner函数里面
寻找,结果却发现找不到。既然在当前函数作用域里面找不到,那么就往上翻一层,在它的父级作用域,也就是test
函数的作用域里面寻找,结果发现找到了。test函数里面定义了一个变量a,但是没有赋值,那么a 就是undefined。
既然已经找到了,那么就不会去全局作用域里面寻找变量a了。所以,全局作用域里面的变量a其实就是一个摆设。
三、参数传递
参数传递:就是函数调用的时候传进来的值
示例:
function add(a,b,c) {
console.log(arguments) // 函数的内部还维护了一个arguments数组 传多个参数都在此数组中
var sum = a + b + c;
console.log(sum)
}
add(1,2,3) // 6 若是传字符串的话会进行拼接
add(1) // NaN a的值是1,b和c的值就是undefined 结果为NaN 代表无法计算
实现多个数字的累加:
function add() {
if(!arguments[0]){ // 如果不存在
return 0;
}
for (var i=1;i<arguments.length;i++){
arguments[0]=arguments[0]+arguments[i]
}
console.log(arguments[0])
}
add(1,2,3,4,5) // 15
方式不唯一:调用函数返回一个结果
function add() {
var sum=0;
for (var i=0;i<arguments.length;i++){
sum+=arguments[i]
}
return sum;
}
var sum= add(1,2,3,4,5,6,7,8,9,10)
console.log(sum) // 55
只传一个参数案例:
function fun(a) {
console.log(a)
}
fun() // undefined
// 进行拆分
function fun() {
var a;
console.log(a)
}
这个参数也属于函数作用域,并没有给这个变量赋值,所以值是undefined
四、闭包
产生闭包的条件:
1、函数内部有一个函数
2、函数内部的函数里面用到了外部函数的局部变量
3、外部函数把内部函数作为返回值return出去
示例:
function test() {
var a = 100;
return function () {
console.log(a)
}
}
test()() // 第一个括号调用test函数,第二个括号才调用内部函数
闭包的好处:
正常情况下,我们调用一个函数,其里面的局部变量会在函数调用结束后销毁,这也是我们在全局作用域里面无法访
问函数局部变量的原因。
但是,如使用了闭包,那么就会让这个局部变量不随着原函数的销毁而销毁,而是继续存在。
比如:我们反复调用这个内部函数,会发现这个变量a一直存在,就好像是一个全局作用域里面的变量。
示例:
function test() {
var a = 100;
return function (increment) {
a=a+increment
console.log(a)
}
}
var inner = test(); // 先获取内部函数
inner(1) // 101
inner(1) // 102
inner(1) // 103
利用这种写法就相当于在全局作用域里面定义了一个变量a,然后在函数中操作全局变量。
这种闭包的形式操作可以减少很多不必要的全局变量。
全局作用域是一块公共区域,如果为了某个单一的功能而定义一个全局变量,则会导致全局变量过多,代码较乱!
这种情况,优先考虑使用闭包。
五、自执行函数
自执行函数:定义之后就立刻执行的函数。
一般是没有名字的,正因为没有名字,所以它虽然会被立即执行,但是只会被执行一次。
语法:(定义一个没有名字的函数)();
示例:
(
function() {
console.log(12345)
}
)
();
自执行函数一般和闭包配合使用
function test() {
var a = 10;
return function (increment) {
a = a + increment;
console.log(a)
}
}
var inner = test();
inner(1) // 11
inner(1) // 12
inner(1) // 13
修改之后:其实真正想要的是test里面的内部函数,不需要知道外部这个函数叫什么,叫什么都无所谓的。
var inner = (function () {
var a = 10;
return function (increment) {
a = a + increment;
console.log(a)
}
})();
inner(2) // 12
inner(2) // 14
inner(2) // 16
inner() // NaN
外部函数只是为了产生闭包环境而临时定义的函数,因此,没必要给外部函数取名字!
六、new 一个函数
this永远指向当前函数的调用者
在全局作用域里面的任何东西,不管是变量还是函数,都属于windows对象。
示例:
function hello() {
console.log(this)
}
var a = 10;
console.log(window.a) // 10
hello()
window.hello() // 效果等同
对象可以通过俩种方式调用里面的属性:
1、点的方式 像 window.hello() 的形式
2、使用中括号,对象[属性名称] 属性名称可以是字符串也可以是变量
形式一:
window’hello’
形式二:
var p = ‘hello’
windowp;
hello函数内部产生了一个新的对象,也就是hello函数的真实调用者
var hello1 = new hello();
console.log(hello1)
这种函数还有一个别称:构造函数,通过构造函数构造一个对象模板。
对象模板:指用一个函数的形式设计一种对象的种类。
示例:
// 使用函数的形式
function Fruit(name,color,smell) {
this.name=name
this.color=color
this.smell=smell
}
var apple= new Fruit(‘苹果’,‘绿色’,‘甜的’)
console.log(apple) // Fruit {name: ‘苹果’, color: ‘绿色’, smell: ‘甜的’}
// 创建对象的一种形式
var apple2 = {
name:‘苹果’,
color:‘绿色’,
smell:‘不甜’
}
console.log(apple2) // {name: ‘苹果’, color: ‘绿色’, smell: ‘不甜’}
除了基本数据类型之外,其他都引用数据类型。
对象就属于引用数据类型。
七、回调函数
回调函数:把一个函数的定义当做参数传递给另一个函数。
正常情况下,函数传参可以是一个数字,也可以是一个字符串,这都没问题。
但是JavaScript提供了一种强大的特性:函数也可以作为另一个函数的参数。
示例:
传统的函数:
function eat(food,howToEat,tiaoliao) {
alert(tiaoliao+" ,"+howToEat+“吃”+food)
}
eat(“羊肉串”,“笑嘻嘻地”,“撒上一撮孜然”)
修改之后:使用回调函数
// callback 就是那个函数 执行eat的时候,直接执行callback,并且把food传入callback
// 在调用eat的时候 通过临时编写一个新的函数实现的
function eat(food,callback) {
callback(food)
}
eat(‘羊肉串’,function (food) {
alert(“笑嘻嘻地,撒上一撮孜然,开心的吃”+food)
})
二、基础考核
1、变量和简单数据类型
简单数据类型:
字符串、数值、布尔、null、undefined
关于函数的说明:
函数之修,第一要义便是理解返回值、 参数列表和函数体。可以把函数想象成一个“黑盒子”,所谓参数,就是丢到
这个黑盒子中的物体,可以是单个物体,也可以是多个物体。黑盒子的内部空间就是函数的函数体!在函数体中,可以
对丢进来的参数进 行处理,处理结束后,如果该函数的设计者认为需要将得到的某个结果 从黑盒子中扔出,作为对于
“黑盒子访问者”的奖赏,就可以使用return 关键字将其抛出。
函数之修,第二要义便是业务逻辑,作为函数的设计者,必须清 楚地明白自己设计这个函数是为了什么。叶小凡
眼中一亮,想到了刚才 化浮为整的过程,因为0.1和0.2都是小数,所以直接相加会产生精度丢失的问题。
要知道:方法就是函数,函数的调用需要括号。
indexOf方法:在原字符串中搜索一个特定的字符串,将目标字符串在原字符串中的位置返回。(下标从0开始)
查询一个不存在的匹配项则返回 -1
replace方法:字符串替换,参数1:需要替换的内容 参数2:替换后的内容
它只能匹配到字符串中的第一个匹配项。
俩数求和可能会遇到的问题
// 计算精度问题 加法和乘法都有这个问题
console.log(0.1+0.2) // 0.30000000000000004
console.log(1.1+1.122) // 2.2220000000000004
console.log(1.001*1000) // 1000.9999999999999
console.log(1+1.02) // 2.02 正常
console.log(301/100) // 3.01 正常
计算俩数之和:
// 计算俩数之和
function add(num1,num2) {
// 将数字转换为字符串
num1 = num1.toString();
num2 = num2.toString();
// 获取小数点的位置
var index1 = num1.indexOf(“.”)
var index2 = num2.indexOf(“.”)
// 如果小数点存在 那么就在获取各自的小数位数
var ws1 = 0;
var ws2 = 0;
if(index1 != -1){
ws1 = num1.split(“.”)[1].length
}
if(index2 != -1){
ws2 = num2.split(“.”)[1].length
}
// 看谁的小数位数大 谁的小数位数小
var bigger = (ws1>ws2)?ws1:ws2
var smaller = (ws1<ws2)?ws1:ws2
// 计算得到需要补齐的0的个数
var zeroCount = bigger - smaller
// 去除小数点
num1 = num1.replace(“.”,“”)
num2 = num2.replace(“.”,“”)
// 比较num1和num2 谁大 比较方法就是看谁是smaller 是smaller的就补0
if(ws1==smaller){
for (var i = 0;i < zeroCount; i++){
num1 += “0”
}
}else {
for (var i = 0;i < zeroCount; i++){
num2 += “0”
}
}
// 开始计算
var sum = parseInt(num1) + parseInt(num2)
// 根据较大的小数位数计算倍数
var times = 1;
for (var i = 0; i< bigger; i++){
times = times*10
}
sum = sum/times
return sum
}
console.log(add(1.01,1.222)) // 2.232
console.log(add(0.1,0.2)) // 0.3
console.log(add(1,0.2)) // 1.3
三、jQuery和DOM
jQuery简介
jQuery封装了 JavaScript常用的功能代码,提供了简便的JavaScript API,优化了HTML 文档操作、事件处理
动画设计和Ajax交互。
jQuery的核心特性可以总结为:具有独特的链式语法和短小清晰的 多功能接口;具有高效灵活的CSS选择器进行扩展
拥有便捷的插件扩 展机制和丰富的插件。
源生JavaScript获取dom元素:
document.getElementById(“id的值”)
使用jQuery获取dom元素:
$(‘#id的值’)
jQuery支持ajax异步无刷新技术
基于jQuery的ajax方法:
$.ajax({
url: ‘’, // 后台请求地址
type: ‘’, // 请求方式 get post
dataType: ‘’, // 接受数据的方式 text json (json 可不写)
data: { // 为后台传递的参数
},
success: function (data) { // 回调函数 后台执行完毕 该函数才执行
// data是responseText,是jQuery处理后的数据
},
error: function () { // 表示当请求发生错误的时候 才执行
}
})
拓展:页面加载即执行jQuery的三种方式
1、$(function(){ … }) // 推荐使用
例如:
$(function () {
$(‘#name’).html(“大哥”);
})
2、 $(document).ready(function(){ … })
是第一种形式的完整形式
3、 window.onload = function(){ … }
记得引入cdn
jQuery选择器
$(“#id”) id选择器
$(“.class名”) class选择器
$(“标签名”) 标签选择器
$(“#id, .class, 标签名”) 组合选择器
$(“*”) 选取当前页面中所有dom对象,通配符选择器
书中有提及:
群组选择器:可以理解为组合选择器,多了class样式之间是有逗号隔开
后代选择器:如果一个标签里面嵌套了另外一个标签,那么里面的标签可以认 为是外面标签的后代。
示例:
inner1
其他案例:例如 点击事件
关于jQuery选择器可以参考:jQuery选择器参考手册
使用jQuery操作dom
示例:
法宝列表
- 天马妖焰钟
- 流魂歧霞伞
- 天网奇火石
- 混沌秘霖扇
- 昊天粗琉斧
1、查找元素
要求:获取第二件法宝
$(document).ready(function () {
$(“#magic”).click(function () {
var ul = $(“ul”);
var lis = ul.find(“li”);
var li = lis.eq(1); // 下标是从0开始的
alert(li.text())
})
})
也可以这样写:这个方法是直接使用后代选择器选择所有li元素,然后用eq方法比较即可
window.onload = function () {
$(“#magic”).click(function () {
var text = $(‘ul li:eq(1)’).text();
// var text = $(‘ul li’).eq(1).text(); // 效果是等同的
alert(text);
})
}
2、查找属性
要求:寻找最后一个li元素的id属性值
// 这里的意思是 获取第四个元素的id属性 固定了li 的个数
var id = $(“ul li”).eq(4).attr(“id”);
alert(id) // a5
// 这里写了俩次ul li 有点重复
var len = $(“ul li”).length;
var id = $(“ul li”).eq(len - 1).attr(“id”)
alert(id) // a5
// 对上面的出现的俩次 ul li 进行优化
var $li = $(“ul li”);
var len = $li.length;
var id = $li.eq(len - 1).attr(“id”)
alert(id) // a5
// 一个特殊的选择器 可阅读jQuery参考手册去进行理解
var id = $(“ul li:last”).attr(“id”)
alert(id) // a5
3、链式调用
核心:合理使用this关键字,以return this 的形式。
原话:刚才的代码中频繁出现对象在调用函数之后,又立刻调用其他函数或者属性的情况,你可知道这是怎么回事,
为什么能够这么写?
示例:
var myFunction = function () {
return {
func01: function () {
console.log(“func01”)
return this;
},
func02: function () {
console.log(“func02”)
return this;
}
}
}
console.log(“正常调用:”)
var obj = myFunction();
obj.func01()
obj.func02()
console.log(“链式调用:”)
obj.func01().func02()
缘由:让func01的返回值变成obj就行了。一个this关键字就可以解决这个问题,因为在函数中,this 关键字永远
指向当前函数的调用者。在这里,调用者自然是obj。
4、创造新的元素
主要就是使用append和appendTo新增节点,也可以理解为追加元素。
// 创建一个新的元素
var newLi = $(“
- 新的法宝
- ”)
newLi.appendTo($(‘ul’))
// 或者 反斜杠 表示转义 只可以使用appendTo
var newLi1 = $(“<li id=“a7”>新的法宝1”)
newLi1.appendTo($(‘ul’))
// 一气呵成
( " < l i i d = ′ a 8 ′ > 新的法宝 2 < / l i > " ) . a p p e n d T o ( ("<li id='a8'>新的法宝2</li>").appendTo( ("<liid=′a8′>新的法宝2</li>").appendTo((‘ul’))
// append方法
( ′ u l ′ ) . a p p e n d ( ('ul').append( (′ul′).append((“
- 新的法宝3
- ”))
// 替换目标元素里面的html代码 这样的话,整个法宝列表只有这一个元素了
( ′ u l ′ ) . h t m l ( ('ul').html( (′ul′).html((“
- 法宝被替换了
- ”))
jQuery插入节点的其他方法:
// 示例
( " < l i i d = ′ a 9 ′ > 新的法 4 < / l i > " ) . i n s e r t B e f o r e ( ("<li id='a9'>新的法4</li>").insertBefore( ("<liid=′a9′>新的法4</li>").insertBefore((‘ul’)) // 在ul 的最上面 外部 加了一个 li
( " < l i i d = ′ a 1 0 ′ > 新的法 5 < / l i > " ) . i n s e r t A f t e r ( ("<li id='a10'>新的法5</li>").insertAfter( ("<liid=′a10′>新的法5</li>").insertAfter((‘ul’)) // 在ul 的最下面 外部 加了一个 li
// 将 新的法宝6 添加到该ul 的最前面
( " < l i i d = ′ a 1 0 ′ > 新的法宝 6 < / l i > " ) . p r e p e n d T o ( ("<li id='a10'>新的法宝6</li>").prependTo( ("<liid=′a10′>新的法宝6</li>").prependTo((‘ul’))
5、删除和隐藏节点
使用 remove 删除节点
使用 hide 隐藏节点
// 删除id为a1的元素
$(“#a1”).remove();
$(“#a2”).hide(); // 隐藏 其实就是给对应的元素设置display:none。
$(“#a2”).show(); // 显示 show方法其实就是把元素的display重新设置为block罢了
6、jQuery操作属性
使用attr方法
// 给元素设置多个属性
// 需要给attr方法传入一个JavaScript对象,对象里面是键值对的集合,
// 每个键值对的格式为key:value,不同的键值对用逗号分隔
$(“#a31”).attr({“name”:“spanDom”,“title”:“赋值标题”})
// 删除属性 传入想要删除的属性名
$(“#a31”).removeAttr(‘name’)
7、内容操作
如何用jQuery设置和获取HTML、文本和值?
text方法用来设置和获取元素的文本内容。 – 无参的时候 获取内容 有参数的时候 替换内容
val方法操作元素的值,传入参数就是给元素赋值,不传参数的话,就是获取元素的值。
html方法的含义是把HTML代码的字符串动态地插入目标元素内部
$(“#list”).html(“新文本内容”)
console.log($(“#list”).text()) // 新文本内容
console.log($(“#list”).html()) // 新文本内容
console.log($(“h3”).html()) // 法宝列表
8、遍历和寻找节点
children方法:获取某个元素的下一代子元素,但不包括孙子辈的元素。
find方法:去寻找指定标签下面的元素
siblings方法:获取同一级别的所有兄弟元素
四、vue的妙处
1、数据绑定
使用vue的时候先引入:
使用v-model 完成数据的双向绑定
示例:
输入的文字:{
{message}}
Vue() 可以理解为一个构造函数,里面传一个参数 也就是json对象,你看:Vue({})
2、v-on 监听事件
v-on 监听事件 可以简化为 @ 效果是一样的
使用场合:鼠标单击、键盘事件、下拉框等
示例:
<input type=“button” @click=“add” value=“点击一下就加1”>
{
{num}}
处理事件冒泡:有如下几种
.stop 阻止事件冒泡: @click.stop=“btn”
.prevent 阻止提交,只对from标签和a标签有效 阻止这种默认的刷新操作
.capture 优先触发
.self 只允许元素自己触发,子元素无法触发
.once 只触发一次
3、条件语句
v-if
v-else
v-else-if
示例:仅为了演示
张三
李四
数据域里面:改变false,看效果,理解
data:{
flag:true
}
4、for循环
示例:
请选择身份: {{role.label}}
data:{
roleList:[
{value:‘1’,label:‘我是游客’},
{value:‘2’,label:‘我是普通用户’},
{value:‘3’,label:‘我是管理员’}
]
}
5、属性绑定 v-bind 简写 :
要加载绑定属性的前面
示例:给optiona绑定value属性
指定默认选中:我是普通用户
请选择身份: {{role.label}}
data:{
role:2,
roleList:[
{value:‘1’,label:‘我是游客’},
{value:‘2’,label:‘我是普通用户’},
{value:‘3’,label:‘我是管理员’}
]
}
6、组件开发
在components 下定义局部组件:定义组件的时候有大写字母,使用的时候写横杠和小写字母
示例1:定义一个按钮组件,基本使用
// 局部组件
components:{
‘coolBtn’:{
props:[‘name’], // 添加组件的属性
template:“”
}
}
示例2:显示不同风格的按钮
components:{
‘coolBtn’:{
props:[‘name’,‘type’], // 添加组件的属性
template:“”
}
}
全局组件:所有页面都可以使用的,最后,在外面建议一个btnUtil.js(名字是任意的) 将代码复制进去
使用的时候,在引入该组件
格式:Vue.component(‘组件名’,{props:[‘属性名’],template:“模板信息”});
7、计算属性:computed 与 data、methods等是平级的
情景导入:商品打折案例
请输入商品价格:
请输入商品折扣:
{{item.label}}
成交价:{
{price*discount}}元
new Vue({
el:‘#app’,
data:{
price:0,
discount:0.9,
discounts:[
{value:‘0.9’,label:‘9折’},
{value:‘0.8’,label:‘8折’},
{value:‘0.7’,label:‘7折’},
{value:‘0.65’,label:‘65折’}
]
},
methods:{
},
computed:{
}
})
当计算过程非常复杂怎么办?
现在要求判断日期,如果当天是11月11号,那么就需要搞促销,规定商 品满200元减50元,满400元减150元
自己可以用今天的日期记性验证一下。
计算属性:
computed:{
payment(){
// 1、获取今天的日期
var today = new Date();
var month = today.getMonth() + 1;
var day = today.getDate();
// 2、根据是否是双十一,获取返利的金额
var rebate = 0;
if(month == 11 && day == 11){
if(this.price>=400){
rebate = 150;
}else if(this.price>=200){
rebate = 50;
}
}
// 3、得到最终的金额
return this.price * this.discount - rebate;
}
}
页面的返回值要改一下:
成交价:{
{payment}}元
8、监听属性:和data、methods平级的
对象篇
模块化编程-自研模块加载器
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
nts:{
‘coolBtn’:{
props:[‘name’,‘type’], // 添加组件的属性
template:“”
}
}
全局组件:所有页面都可以使用的,最后,在外面建议一个btnUtil.js(名字是任意的) 将代码复制进去
使用的时候,在引入该组件
格式:Vue.component(‘组件名’,{props:[‘属性名’],template:“模板信息”});
7、计算属性:computed 与 data、methods等是平级的
情景导入:商品打折案例
请输入商品价格:
请输入商品折扣:
{{item.label}}
成交价:{
{price*discount}}元
new Vue({
el:‘#app’,
data:{
price:0,
discount:0.9,
discounts:[
{value:‘0.9’,label:‘9折’},
{value:‘0.8’,label:‘8折’},
{value:‘0.7’,label:‘7折’},
{value:‘0.65’,label:‘65折’}
]
},
methods:{
},
computed:{
}
})
当计算过程非常复杂怎么办?
现在要求判断日期,如果当天是11月11号,那么就需要搞促销,规定商 品满200元减50元,满400元减150元
自己可以用今天的日期记性验证一下。
计算属性:
computed:{
payment(){
// 1、获取今天的日期
var today = new Date();
var month = today.getMonth() + 1;
var day = today.getDate();
// 2、根据是否是双十一,获取返利的金额
var rebate = 0;
if(month == 11 && day == 11){
if(this.price>=400){
rebate = 150;
}else if(this.price>=200){
rebate = 50;
}
}
// 3、得到最终的金额
return this.price * this.discount - rebate;
}
}
页面的返回值要改一下:
成交价:{
{payment}}元
8、监听属性:和data、methods平级的
对象篇
模块化编程-自研模块加载器
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】