希望能够帮助更多的小伙伴。加我????即可交流问题(不是大佬,互相学习,创造良好的学习环境)。以下哪些你不懂呢?
Parent.apply(this)
super()
方法,然后再用子类的构造函数修改thisconstructor
方法中调用super
方法,否则新建实例报错<div id="dadaqianduan">我喜欢你</div>
document.getElementById("dadaqianduan").innerHTML; // 我喜欢你
document.getElementById("dadaqianduan").outerHTML;
// <div id="dadaqianduan">我喜欢你</div>
image.png
示例:
function fun(value) {
if(value) {
var da = "掘金魔王哪吒";
return da;
} esle {
// da 在此处可访问,值为undefined
return null
}
// da 在此处可访问,值为undefined
}
你如果以为value的值为true时,变量da才会被创建,那就错了,实际上da无论如何都会被创建,如下代码所示:
function fun(value) {
var da;
if(value) {
da = '魔王哪吒';
return da;
} else {
return null;
}
}
es6引入了块级作用域,让变量的声明周期更加可以控制
创建:
块级作用域:
let声明
在项目中常用let来代替var进行变量声明(let声明会将变量的作用域限制在当前代码块中)
function fun(value) {
if(value) {
let da = "掘金魔王哪吒";
return da;
}else{
// da 在此处不可用
return null;
}
// da 在此处不可用
}
如果value为false时,该变量时永远都不会被声明并初始化的哦~
如下:不可以重复声明的哟~
var da = '魔王哪吒';
// 语法错误
let da = '魔王哪吒好帅';
image.png
有图有真相
记住:let不能在同一作用域内重复声明一个已有标识符,注意时同一作用域内,如果时在嵌套的作用域内使用let声明一个同名的新变量,就不会抛出错误,我只说同一作用域内会报错,不在同一作用域内就不会报错了哟~
var da = 12;
// 不会抛出错误
if (true) {
let da = 123;
}
image.png
常量的声明
constant
,表示它们的值被设置完成后就不能再被改变了所以啊,所有的const声明的变量都需要(在声明时)进行初始化:
// 有效的常量
const da = 12;
// 语法错误:未进行初始化
const dada;
image.png
示例:
if(value) {
const da = '掘金魔王哪吒'
}
// da 在此处无法访问
无论是在严格模式还是非严格模式下:对之前用const声明的常量进行赋值会抛出错误
const da = '掘金:魔王哪吒,好帅'
da = '是很帅的,魔王哪吒' // 抛出错误
const声明常量,如果使用const声明对象如下描述:
const声明 会阻止对于 变量绑定 与 变量自身值的修改,这意味着 const 声明并不会阻止对变量成员的修改。
阻止:变量绑定,变量自身值的修改
不阻止:变量成员的修改
示例:
// dada 在初始化时绑定了带有一个属性的对象
const dada = {
string: 'dadaqianduan.cn亿万少女的梦'
};
// 正常
dada.string = '掘金魔王哪吒:亿万少女的梦';
// 抛出错误
dada = {
string: '魔王哪吒,你在做梦呢'
};
image.png
暂时性死区
什么是暂时性死区呢?就是之前说过,使用let或者是const声明的变量,在没有达到声明处之前是无法访问的,如果访问会导致引用错误。就算是在安全情况下,也是一样。
如下:
if(value) {
console.log(typeof da); // 引用错误
let da = '达哥好帅';
}
image.png
当js引擎检视代码块并发现变量声明时,它会在面对 var 的情况下将声明提升到 函数或全局作用域的顶部,而面对 let 或 const 时会将声明放在暂时性死区内。
任何在暂 时性死区内访问变量的企图都会导致“运行时”错误(runtime error)。只有执行到变量的声明 语句时,该变量才会从暂时性死区内被移除并可以安全使用。
示例:
那么在变量被定义的代码块之外对该变量使用typeof,尽管其结果可能并非预期:
console.log(typeof da); // 'undefined'
if(true) {
let da = 'dadaqianduan';
}
image.png
循环内的函数
// 因为 var 声明导致了变量提升。
for (var i = 0; i < 10; i++) {
...
}
// i 在此处仍然可被访问
console.log(i); // 10
for (let i = 0; i < 10; i++) {
...
}
// i 在此处不可访问,抛出错误
console.log(i);
for(var i=1;i<=5;i++) {
setTimeout(() => {
console.log(i)
}, i*1000)
}
会打印出6个6,原因:for循环中用var来申明变量i,此时var存在变量提升问题,并且6次循环中全都共用一个变量,所以当setTimeout中的延迟函数开始执行时,循环已经结束,此时i=6,所以会打印出6个6。
变量i在循环的每次迭代中都被共享了,表示循环内创建的那些函数都拥有对于同一变量的引用。
利用闭包可以解决这个问题:
for(var i=1;i<=5;i++) {
(function(j){
setTimeout(() => {
console.log(j)
}, j* 1000)
})(i)
}
(IIFEs)
,以便在每次迭代中 强制创建变量的一个新副本for(var i=1;i<=5;i++) {
setTimeout((j) => {
console.log(j)
}, i* 1000, i)
}
for(let i=1;i<=5;i++) {
setTimeout(() => {
console.log(i)
}, i*1000)
}
循环内的let声明
示例:
var arr = [],
object = {
a: 1,
b: 2,
c: 3
};
for(let key in object) {
arr.push(function(){
console.log(key);
});
}
arr.forEach(function(func){
func(); // a,b,c
});
image.png
循环内的常量声明
示例:
// 在一次迭代后抛出错误
for(const i = 0; i < 10; i++){..}
for-in 或 for-of
var arr = [],
object = {
a: 1,
b: 2,
c: 3
};
// 不会报错
for(const key in object) {
arr.push(function(){
console.log(key);
});
}
arr.forEach(function(func){
func(); // a,b,c
});
image.png
注意:使用const声明,不能改变值,上述是 循环为每次迭代创建了一个新的变量绑定,而不是试图去修改已绑定的变量的值。
使用var,在全局作用域中,它会创建一个新的全局变量,并成为全局对象的一个属性,可能当你使用var时,需要注意的时,var可能会无意覆盖一个已有的全局属性。使用var声明,定义为全局变量后会立即成为window的一个属性。
如果你在全局作用域上使用let或者时const,会在全局作用域上创建新的绑定,但不会被添加到全局对象上,不能使用let或const来覆盖一个全局变量,你只能用来起到屏蔽效果。
描述:
( TDZ )
, 试图在声明位置之前访问它就会导致错误。textContent
会获取style="display:none
中的文本,而innerText
不会textContent
会获取style
标签里面的文本,而innerText
不会textContent
不会理会html
格式,直接输出不换行的文本innerText
会根据标签里面的元素独立一行innerText
会根据标签里面的元素独立一行innerText
对IE
的兼容性较好textContent
虽然作为标准方法但是只支持IE8+
以上的浏览器el.children
和el.childNodes
的区别el.children
,返回指定节点的所有element
子节点,即返回节点元素el.childNodes
,返回指定节点的所有子节点,包括节点元素和文本元素image.png
JavaScript
代码放到文档<head>
标签中的<script
标签之间<head>
部分放一个<script>
标签,并把它的src
属性指向该文件<script>
标签放到HTML文档的最后,</body>
标签之前(这样能使浏览器更快加载页面)typeof
操作符可以告诉我们它的操作数是一个字符串,数值,函数,布尔值还是对象。变量作用域:分全局,局部。
getElementById
getElementsByTagName
getElementsByClassName
getAttribute
setAttribute
JavaScript语言里的对象
获取元素节点的方法:通过元素ID,通过标签名,通过类名字
getElementById
,这个方法将返回一个与那个给定id
属性值的元素节点对应的对象。document.getElementById(id)
getElementsByTagName
,这个方法返回一个对象数组,每个对象分别对应着文档里有着给定标签的一个元素。element.getElementsByTagName(tag)
getElementsByClassName
,这个方法能够通过Class属性中的类名来访问元素获取和数值属性:
getAttribute
方法就是用来获取属性-object.getAttribute(attribute)
setAttribute
方法可以用来更改属性节点的值-object.setAttribute(attribute,value)
示例:
var node = document.getElementsByTagName("p");
for(let i=0, i<node.length; i++){
console.log(node[i].getAttribute("title"));
}
var node = document.getElementsByTagName("p");
node.setAttribute("title","dadaqianduan.cn");
a
标签target
属性决定_blank
在新窗口中打开被链接文档_self
默认,在相同的框架中打开被链接文档image.png
带有参数默认值的函数:
// es5
function Fun(da, da2) {
da = da || 'dadaqianduan';
da2 = da2 || '1024bibi.com';
}
升级改造,typeof
来检测参数的类型:
function fun(da) {
da = (typeof da !== 'undefined") ? da : 'dadaqianduan';
}
// es6
funtion da(da='掘金魔王哪吒', callback = function(){}) {
}
参数默认值如何影响arguments对象
如下所示:
function fn(a) {
console.log(a === arguments[0]);
a = '达达前端';
console.log(a === arguments[0]);
}
fn('dadaqianduan');
image.png
function fn(a) {
"use strict";
console.log(a === arguments[0]);
a = '达达前端';
console.log(a === arguments[0]);
}
fn('dadaqianduan');
image.png
参数默认值表达式
示例:
function getValue() {
return 1;
}
function add(a, b = getValue()) {
return a + b;
}
console.log(add(1,1)); // 2
console.log(add(2); // 3
let value = 5;
function getValue() {
return value++;
}
function add(a,b=getValue()) {
return a+b;
}
console.log(add(1,1)); // 2
console.log(add(1)); // 6
console.log(add(1)); // 7
function add(a,b=a) {
return a + b;
}
console.log(add(1,1));
console.log(add(1));
function getValue(value) {
return value + 5;
}
function add(a, b = getValue(a)) {
return a + b;
}
console.log(add(1,1)); // 2
console.log(add(1)); // 7
function add(a = b, b) {
return a + b;
}
console.log(add(1,1)); // 2
console.log(add(undefined,1)); // 抛出错误
参数默认值的暂时性死区
es5中的不具名参数
示例:
function da(object) {
let result = Object.create(null);
for(let i = 1, len = arguments.length; i<len; i++) {
result[arguments[i]] = object[arguments[i]];
}
return result;
}
let book = {
a: '1',
b: '2',
c: '3'
};
let da1 = da(book, 'a', 'b');
console.log(da1.a); // 1
console.log(da2.b); // 2
剩余参数
剩余参数由三个点(...)与一个紧跟着的具名参数指定。
function fn(object, ...keys) {
let result = Object.reate(null);
for(let i = 0, len = keys.length; i<len; i++) {
result[key[i]] = object[keys[i]];
}
return result;
}
let object = {
// 语法错误:不能在setter中使用剩余参数
set name(...value) {
// 一些操作
}
};
function fn(...args) {
console.log(args.length);
console.log(arguments.length);
console.log(args[0], arguments[0]);
console.log(args[1], arguments[1]);
}
fn("a","b");
// 2
// 2
// a a
// b b
函数构造器的增强能力(es6默认参数以及剩余参数)
var add = new Function("a", "b", "return a + b");
console.log(add(1,1)); // 2
var da = new Function("a", "b=a", "return a+b");
console.log(da(1,1)); // 2
console.log(da(1)); // 2
扩展运算符
示例:
// es5
let arr = [1,2,3,4,5];
console.log(Math.max.apply(Math, arr)); // 5
// es6
let arr = [1,2,3,4,5];
console.log(Math.max(...values)); // 5
let arr2 = [-2,-3,-4];
console.log(Math.max(...arr2, 0)); // 0
es6函数名称属性
示例:
function da() {}
console.log(da.name); // da
var dada = function() {}
console.log(dada.name); // dada
image.png
名称属性的特殊情况
image.png
明确函数的双重用途:当使用new时,函数内部的this是一个新对象,并作为函数的返回值。
当函数未使用 new 进行调用时, call
方法会被执行,运行的是代码中显示的函数体。
当函数使用 new 进行调用时, Construct
方法则会被执行,负责创建一个被称为新目标的新的对象,并且使用该新目标作为 this 去执行函数体。
es6引入new.target元属性
function Fun(value) {
if(this instanceof Fun) {
this.value = value;
} else {
throw new Error("dadaqianduan");
}
}
var da = new Fun("dada");
var dadaqianduan = Fun("123"); // 报错
function Fun(value) {
if(this instanceof Fun) {
this.value = value;
} else {
throw new Error("dadaqianduan");
}
}
var da = new Fun("dada");
var dadaqianduan = Fun.call(da, "dadaqianduan"); // ok
function Fun(value) {
// 是否被定义
if(typeof new.target !== "undefined") {
this.value = value;
}else{
throw new Error("dadaqianduan.cn");
}
}
var da = new Fun("jeskson");
var da2 = Fun.call(da, 'jeskson'); // 报错
function Fun(value) {
if(new.target === Fun) {
this.value = value;
}else{
throw new Error("dadaqianduan.cn");
}
}
function Da(value) {
Fun.call(this, name);
}
var person = new Fun("dadaqianduan.cn");
var person1 = new Da("dadaqianduan.cn"); // 报错
uni.openBluetoothAdapter(OBJECT)
uni.startBluetoothDevicesDiscovery(OBJECT)
uni.onBluetoothDeviceFound(CALLBACK)
uni.stopBluetoothDevicesDiscovery(OBJECT)
uni.createBLEConnection(OBJECT)
uni.getBLEDeviceServices(OBJECT)
uni.getBLEDeviceCharacteristics(OBJECT)
notify
功能uni.notifyBLECharacteristicValueChange(OBJECT)
uni.onBLECharacteristicValueChange(CALLBACK)
初始化蓝牙(检测一下手机蓝牙是否打开)
uni.openBluetoothAdapter({
success:(res) => {
// 已打开
uni.getBluetoothAdapterState({ // 蓝牙的匹配状态
success: (res1) => {
console.log(res1, "本机设备的蓝牙已打开")
// 开始搜索蓝牙设备
this.startBluetoothDeviceDiscovery()
},
fail:(error)=>{
uni.showToast({icon:'none',title:'查看手机蓝牙是否打开'
}
});
},
fail: (err) => {
// 未打开
uni.showToast({icon:'none',title:'查看手机蓝牙是否打开'});
}
})
开始搜索蓝牙设备
startBluetoothDeviceDiscovery() {
uni.startBluetoothDevicesDiscovery({
success:(res) => {
console.log('startBluetoothDevicesDiscovery success', res)
// 发现设备
this.onBluetoothDeviceFound()
},
fail:(err) => {
console.log(err, '错误信息');
}
})
}
发现设备,获取设备id
onBluetoothDeviceFound() {
uni.onBluetoothDeviceFound((res) => {
// 搜索到的设备存储起来
if(this.list.indexOf(res.devices[0].deviceId) === -1){
this.list.push(res.devices[0].deviceId)
}
})
}
点击选择自己需要连接的设备,连接蓝牙设备
createBLEConnection(deviceId) {
this.deviceId = deviceId
// 连接蓝牙
uni.createBLEConnection({
deviceId: this.deviceId,
success:(res) =>{
this.stopBluetoothDeviceDiscovery()
console.log("蓝牙连接成功")
},
fail:(res) =>{
console.log('蓝牙连接失败',res)
}
})
}
连接成功后,要停止搜索设备
stopBluetoothDevicesDiscovery(){
uni.stopBluetoothDevicesDiscovery({
success: e=> {
this.loading = false
console.log('停止搜索蓝牙设备:' + e.errMsg);
},
fail: e=> {
console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);
}
});
}
获取蓝牙设备所有服务,setTimeout等待一秒种再去获取,直接获取我们可能出现获取不到的情况
//获取蓝牙特征
getBLEDeviceCharacteristics(){
console.log("进入特征");
setTimeout(()=>{
uni.getBLEDeviceCharacteristics({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId:this.deviceId,
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
serviceId:this.serviceId,
success:(res)=>{
console.log(res,'特征getBLEDeviceCharacteristics')
this.characteristics = res.characteristics
console.log(this.characteristics)
//循环所有的uuid
res.characteristics.forEach((item)=>{
if(item.uuid.indexOf("LD") != -1){
console.log('characteristicId:', item.uuid)
//利用传参的形势传给下面的notify,这里的uuid如果都需要用到,就不用做判断了,建议使用setTimeout进行间隔性的调用此方法
this.notifyBLECharacteristicValueChange(item.uuid)
}
})
},
fail:(res)=>{
console.log(res)
}
})
},1000)
},
启用蓝牙设备特征值变化时的 notify 功能
“properties”: {
“read”: true, //读
“write”: true, //写
“notify”: true, //广播
“indicate”: false
}
// 启用 notify 功能
notifyBLECharacteristicValueChange(characteristicId){
console.log(characteristicId,'characteristicId')
uni.notifyBLECharacteristicValueChange({
state: true, // 启用 notify 功能
deviceId:this.deviceId,
serviceId:this.serviceId,
characteristicId:characteristicId,
success:(res)=> {
console.log(res)
// console.log(this.characteristicId)
console.log('notifyBLECharacteristicValueChange success', res.errMsg)
},
fail:(res)=> {
console.log('notifyBLECharacteristicValueChange success2', res.errMsg)
}
})
},
等待:
//获取蓝牙的所有服务
getBLEDeviceServices(){
setTimeout(()=>{
uni.getBLEDeviceServices({
deviceId:this.deviceId,
success:(res)=>{
console.log('device services:', res)
res.services.forEach((item)=>{
if(item.uuid.indexOf("LD")!=-1){
// this.serviceId = item.uuid;
//存储到状态
this.$store.commit("upserviceId",item.uuid)
console.log(this.serviceId)
// 这里获取回调,读取成功就的值就会在这个地方接收到!!!
uni.onBLECharacteristicValueChange((res)=>{
console.log("监听成功",res)
//res.value是ArrayBuffer类型的,官方给了一个方法转16进制,我们再进行操作
this.shiliu = this.ab2hex(res.value)
})
this.getBLEDeviceCharacteristics()
}
})
}
})
},1000)
}
读取蓝牙设备
示例:
//在页面加载时候初始化蓝牙适配器
uni.openBluetoothAdapter
// 初始化完毕开始搜索
this.startBluetoothDeviceDiscovery()
console.log("开始搜寻智能设备");
uni.startBluetoothDevicesDiscovery
success: res => {
self.onBluetoothDeviceFound();
},
onBluetoothDeviceFound
console.log('开始监听寻找到新设备的事件');
stopBluetoothDevicesDiscovery
uni-app蓝牙:
// 代码
//初始蓝牙模块
this.pDeviceInfo = uni.getStorageSync('deviceInfo');
if(!!this.pDeviceInfo){
this.prevConnected = true;
}
initBluetoothModule(){
//初始蓝牙模块
uni.openBluetoothAdapter({
success:res=> {
this.searchBlueList();
},
fail:err=>{
console.log(err)
}
})
},
searchBlueList(){
//开启蓝牙搜索
uni.startBluetoothDevicesDiscovery({
success:res=> {
setTimeout(()=>{
this.getBlueList();
uni.showToast({
title: '开启成功',
icon: 'success',
duration: 1000
});
},1000);
},
})
},
getBlueList(){
//获取搜索列表
uni.getBluetoothDevices({
success:res=> {
let data = res.devices
let tempList=[];
data.map(device=>{
if(!!device.localName){
tempList.push(device)
}
});
this.deviceNum = tempList.length;
this.deviceList=tempList;
this.listenBluetooth();
}
});
},
listenBluetooth(){
let tempList =this.deviceList;
//监听蓝牙搜索
uni.onBluetoothDeviceFound((res) => {
let flag = false;
res.devices.forEach(device => {
if(!!device.localName){
tempList.push(device)
flag =true;
}
})
if(flag){
this.deviceList=tempList;
this.deviceNum = this.deviceList.length;
}
})
},
connetBlue(type,index){
let deviceIndex = index;
let deviceInfo = this.deviceList[deviceIndex];
if(this.prevConnected && type == 1){
deviceInfo = this.pDeviceInfo;
}
let dId = deviceInfo.deviceId;
uni.showLoading({
title: '正在连接...', //提示的内容,
mask: true
});
//连接蓝牙
uni.createBLEConnection({
deviceId: dId,//设备id
success: res=> {
uni.hideLoading();
if(res.errCode == 0){
this.connected = true;
this.connectedName=deviceInfo.name;
uni.setStorageSync('deviceInfo',deviceInfo);
this.deviceId=dId;
uni.showToast({
title: '连接成功',
icon: 'success',
duration: 1000
});
}
uni.stopBluetoothDevicesDiscovery({
success: res => {
console.log('连接蓝牙成功之后关闭蓝牙搜索');
}
})
},
fail:err=>{
uni.showToast({
title: '连接失败!',
icon: 'none',
duration: 2000
});
}
})
},
getBLEDeviceServices(){
//获取服务
uni.showLoading({
title: '正在打印...', //提示的内容,
mask: true
});
let deviceId = this.deviceId;
uni.getBLEDeviceServices({
deviceId,
success: (res) => {
for (let i = 0; i < res.services.length; i++) {
if (res.services[i].isPrimary) {
this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid);
}
}
},
fail: (res) => {
uni.hideLoading();
console.log("获取蓝牙服务失败:" + JSON.stringify(res))
}
})
},
//获取单个服务的特征值(characteristic)
getBLEDeviceCharacteristics(deviceId, serviceId){
if(!!this.characteristics && !!this.serviceId){
this.PrintStr();
return;
}
uni.getBLEDeviceCharacteristics({
deviceId,
serviceId,
success: (res) => {
uni.hideLoading();
for (let i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i];
if (item.properties.write && !this.serviceId) {
this.serviceId = serviceId;
this.characteristics = item.uuid;
this.PrintStr();
}
}
},
fail(res) {
uni.hideLoading();
console.error('获取特征值失败:', res)
}
})
},
closeBluetoothAdapter(){
uni.closeBluetoothAdapter({
success: res => {
console.log('关闭蓝牙适配器');
}
});
},
onUnload() {
this.closeBluetoothAdapter();
}