javascript只有函数作用域,没有块级作用域。即在
dunction
里面定义的变量是有作用域的,if、for等代码块定义的变量是没有作用域的。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>ES6语法-var-const-let用法详解</title>
</head><body><div id="app"><button>测试1</button><button>测试2</button><button>测试3</button></div><script>//作用域代码if(true){//externalVal没有作用域var externalVal = "externalVal";}function domainTest(){var funVal ="funVal";//这里可以访问到externalVal和funValconsole.log(externalVal + "----" + funVal);}domainTest()if(true){console.log(externalVal); //可以访问到externalVal//console.log(funVal); 这一行访问不到变量,报错}//使用var定义变量的局限性var btns = ElementsByTagName('button')for(let i = 0;i < btns.length;i++){btns[i].onclick = function(){alert("点击了第" + (i+1) + "个按钮");}}</script>
</body>
</html>
在上面代码中添加三个button,然后定义监听
然后测试结果如下:
为什么会一直出现的是3呢?这是因为作用域,for代码块没有作用域,当循环for结束的时候,监听的i是几?肯定是3,那么当我们点击按钮的时候i就是3。所以打印出来的就是"点击了第三个按钮"
var作用域在js中存在的缺陷,在ES6版主中,使用新的定义变量let就可以解决。
//使用var定义变量的局限性var btns = ElementsByTagName('button')for(let i = 0;i < btns.length;i++){btns[i].onclick = function(){alert("点击了第" + (i+1) + "个按钮");}}
结果如下:
点击第1个按钮,打印“点击了第3个按钮”的情况就不会再出现。因为let定义的变量自带块级作用域。
当我们希望定义的变量不要被二次赋值的时候(也就是常量),使用const关键字来定义。
const c = 80;
c = 100;//报错
const c; //报错,常量定义的时候必须赋值
function Player(name,age){//定义对象this.name = name;this.age = age;}//定义对象的成员函数Print = function(){alert(this.name + "---" + this.age)}var player1 = new Player("james",35);var player2 = new Player("kobe",39);Print() //james---35 调用函数方法Print() //kobe---39
结果如下:
ES5中对象最令人觉得繁琐的就是构造函数、prototyp、依靠原型链实现继承。因为它使用的不是面向对象的语法,所以使用过程比较混乱。下面我们结束如何使用简介的ES6语法定义对象和继承的增强语法。
ES6语法中,js引入了传统的面向对象编程语法(和java相似)。新的写法比较符合面向对象思想,也比较容易理解。
//class定义对象class Player{//constructor 定义构造函数constructor(name,age){console.log(name + 'fdasfada' + age)this.name = name;this.age = age;}//定义方法toPrint(){console.log(this.name + "---" + this.age)}}//使用对象let player1 = new Player("james",35);//使用对象方法Print() //james---35
引入class关键字,用于定义对象
构造函数方法名称固定,就叫做constructor。
在对象定义类中,this关键字代表当前实例对象
class BestPlayer extends Player{constructor(){super()this.name = "jordan"this.age = 49}}let bestPlayer = new BestPlayer();Print() //jordan---49
通过class关键字实现了类的继承
通过super()关键字调用父类构造函数,如果不传参数,默认是undefined
super()方法必须显示调用,否则子类找不到this指针。
let name = "curry"let age = 33let player3 = {name :name,age : age,toPrint:function(){console.log(player3) //{name: "curry", age: 33}}}Print() //{name: "curry", age: 33, toPrint: ƒ}
可以发现,箭头函数方法写的很简单,箭头左侧定义参数,右侧定义函数体。
//class 定义对象 class Player{//constructor 定义构造函数 constructor(nickname,age){this.nickname = nickname;this.age = age;}//定义成员方法toPrint(){console.log(this.nickname + "---" + this.age)}}
在对象中,this指针指向的就是对象本身。可以this可以引用对象的属性和方法。
graph LR调用d定义组件 --> 调用Vueponent组测组件 --> 在vue实例试图范围内使用组件
子组件
const firstComponent= d({
template:<div> <span>template用于定义组件试图</span> <h3>测试组件</h3> <h2>测试组件内容</h2> </div>
});
//组测组件
Vueponent(“firstComponent”,firstComponent);
var app = new Vue({
el: ‘#app’
});
* 全局组件要**先定义d()**,**在注册vueponent()**,任何**再使用**。* `template`用于定义组件视图* 如果用new VUE()定义多个vue实例,全局组件可以跨多个实例使用* 通常组件定义的名称为首字母大写,驼峰标志。如:firstComponent* 在dom中使用组件,通常遵循使用“-”分隔单词,小写规范。如:first-component最终结果如下:### 全局组件简写 > 使用Vueponent()方法 + template组件视图层模板一步完成全局组件的定义与注册
//组测组件
Vueponent(“secondComponent”,{
template:<div> <span>template用于定义组件二合一试图</span> <h3>测试组件二合一</h3> <h2>测试组件二合一内容</h2> </div>
});
### 局部私有组件> 局部私有组件和全局组件的区别在于,私有组件只能在定义它的实例或者父组件里面使用。如下:定义的组件thirdComponent只能在`<div id="app3">`里面使用,其他vue实例无法使用该组件。
### 父子组件嵌套
子组件
一个父组件Parent里面包含两个子组件Child,并将父组件放在app2实例页面渲染范围内。下文中是使用私有局部组件的方式定义的。也就是Parent组件是app2实例的私有局部组件,Child是Parent组件的私有局部组件。
结果如下:### 父子组件间数据定义和访问
var app = new Vue({
el: ‘#app2’,
components:{
secondComponent:{
template:’#secondComponent’,
data:function(){
return {count:0}
},
methods:{
incr(){
unt++;
}
}
}
}
});
* `secondComponent`组件有自己的视图模板template#secondComponent* `secondComponent`组件有自己的数据定义,data()函数。**这里定义的是一个函数,而不是对象,通过函数返回对象数据**。* `secondComponent`组件有自己的操作方法,定义在methods代码块中#### 父子组件的数据访问
{{childMsg}}
{{parentMsg}}
父组件是没有办法直接访问子组件的数据的,子组件也没有办法直接使用父组件的数据,那么就出现了、children、$ref我们希望在子组件中使用this.打印父组件信息,在父组件中调用children[0]打印子组件信息 上面的方法中,父组件使用this.$children[0]来获取多个子组件的数据。如果我们希望快速的,从父组件获取子组件的数据,还可以为子组件加上一个属性ref。相当于为子组件起了一个别名,便于查找。 然后父组件通过如下代码即可打印子组件的属性数据:
console.log(this.$refs.childRef.childMsg)
使用props父组件向子组件传递数据
------------------
* 父实例将自己数据msg,传递给child* 子组件通过绑定属性child-msg绑定父组件数据msg* 子组件标签属性child-msg对应子组件模型定义属性props:childMsg* childMsg属性可以使用插值表达式,显示template模板里面### props数据通常我们定义一个组件是应该可以提供给其他模块或其他人使用的。使用者可能对该组件的用法并不熟悉,可能会导致错误。所以有必要在子组件内,对父组件传递过来数据进行校验。子组件向父组件传播事件 --------------父组件可以通过和ref的方式获取子组件的数据。但是在实际开发过程中,还有另外一种需求,即:子组件中发生了某些动作,从而改变了子组件的数据。那么父组件如何实时的监听到子组件数据的变化呢?那就是我们这一小节需要讲的核心内容* 在子组件使用$emit(‘事件名称’,参数),触发并发送事件,并且可以通过参数传值
methods:{
incr(){
unt++
this.KaTeX parse error: Expected 'EOF', got '}' at position 38: …count) }̲, decr(…emit(‘decrement’,unt)
}
}
* 在父组件中嵌入子组件,并使用v-on指令(简写为@)监听事件,从而触发回调函数,回调函数接受子组件发送的参数。图中changePcounter就是针对increment事件和decrment事件监听的回调函数
* 父组件定义回调函数接收实践触发源传递的参数,即$emit的第二个参数
changePCounter(counter){
this.pCounter = counter
}
### 整体需求的实现子组件与视图的定义。子组件点击加一按钮触发incr函数,incr函数触发increment事件,并将当前cCounter作为事件参数传递出去。父组件范围监听到increment事件,从而触发changePCounter方法,该方法接受cCounter作为参数。父组件的定义 如果您觉得本文不错,欢迎关注,点赞,收藏支持,您的关注是我坚持的动力! 原创不易,转载请注明出处,感谢支持!如果本文对您有用,欢迎转发分享!
本文发布于:2024-02-04 06:25:44,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170701004753091.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |