JavaScript
JavaScript由三部分组成
ecmascript(制定标准) bom(浏览器对象模型) dom(文档对象模型)
dom级别也就是dom标准
dom1级只规定了dom html 和dom core
dom2级 规定了事件等
JavaScript是一种面向对象的动态性脚本语言
JavaScript有六种数据类型
- Number
- array
- undefined
- Boolean
- object
- String
- symbol(es6新增 属于基本类型 )
可以通过typeof来区分变量类型
其中null 为object 被识别为空引用
遇到函数会返回function
NaN为number
其中值类型或者基本类型存放在栈 引用类型存放在堆栈存放的是指向堆的地址
基本类型分配的内存是标准分配 引用类型因为不确定大小所以会有内存泄漏的风险
要检测引用类型instanceof 可以通过这个运算符
要注意是一个运算符在左边放要检测的变量右边放要检测的目标类型
会返回一个bool值来确定是否是检测类型
执行环境
在es6发布之前只有函数作用域和全局作用域
全局是一个ao对象 全局变量是Window下面的属性
使用var声明变量会有提升 如果一个变量在使用后声明也是可以的
函数也会提升
在函数内部能够访问外部的变量 外部无法访问内部的
如果遇到两个相同变量 优先使用最近的
在es6中增加了块级作用域 增加了两个声明符号 let 和 const
需要注意的是这两个标识符声明的变量不存在提升却有死区的问题
变量必须在声明后才使用 如果一个变量用这两个声明符声明了在没有被执行到时前面所有的同名变量都不能使用
引用类型和值类型
引用类型传递传递的是引用
值类型是按值传递
引用类型堆存放的数据 栈存放的是地址的引用 内存分配是不固定的
值类型存放在栈 内存分配是标准分配
所以引用类型需要进行内存管理
对象
一种无序属性的集合 封装了属性和方法
一种特定东西的集合
js不是一种面向对象的语言是基于对象的语言
面向对象的特点:封装 继承 多态
封装:把固定的方法包装起来给定一个接口实现某个方法
继承:类与类的概念 js中是基于原型继承
多态: 同一个行为,针对不同的对象产生了不同的效果
类:把对象的公有属性抽离出来形成的集合
面向对象从执行者变成指挥者
创建对象
//字面量
let obj = {}
//调用构造函数
let obj = new Object()
// 自定义构造函数
//工厂模式
function Person(name,age){
var obj = new Object()
obj.name = name
obj.age = age
obj.hello =function(){
console.log(obj.name)
}
return
}
工厂模式 new出来的对象是当前对象
自定义构造函数是通过this来标识
自定义函数创建实例时需要new 操作符
New的时候发生的事情
- 开辟内存空间
- 把this指向当前对象
- 设置属性和方法
- 返回当前对象
console.dir可以输出对象结构
_proto_ 指向构造的函数
可以用来判断一个实例是否由该构造函数创建的
换句话来说就是是否是属于那一类的
也可以使用 obj instanceof constructor 来判断
_proto_不是标准的属性
class Per{
constructor(arg) {
this.a = arg
}
sayname(){
console.log(this.a)
}
}
let sum = new Per()
console.log(sum instanceof Per) //true
console.log(sum.constructor == Per)//true
prototype原型链
可以在原型链上添加方法达到数据共享和节省空间
//peototype是标准接口给程序员使用的
//_perto_是给浏览器用的
Json
Josn是一种简单的JavaScript对像
是一种key value 类型的
可以用fro in 来遍历 key 为index 值为Json[key]
let hahah = {
"name":"zhangshan",
"age":29
}
for(let key in hahah){
console.log(key) //name,age
console.log(hahah[key])//zhangsan,29
}
面向对象修改元素的属性
考虑到对象的可复用性所以设计了一个类
其中有一个div 和一个按钮
考虑到有可能需要同样的需求所以分离出来
利用es6语法糖进行仿lei设计
设计了几个接收量 修改的对象,触发对象,修改属性,修改的值
其中修改属性和修改值用了json可以一次修改多个数据
<style type="text/css">
div {
width: 300px;
height: 400px;
background-color: red;
}
</style>
<body>
<div class="hh">
</div>
<button type="button" class="btn"></button>
<script type="text/javascript">
class Div{
constructor(element1,element2,value) {
this.Name = document.querySelector(element1)
this.Name1 = document.querySelector(element2)
this.value = value
}
change(){
//这里的this指向的是实例对像
//this指向被调用的那个对像
//由于我们后面使用了事件处理函数 但事件处理函数调用时
//this指向了调用的那个他所有我们上面属性就不能访问了
//这时候我们拿一个变量来存储前面的this
let that = this
//存储实例对像的this来达到调用实例对象的方法和属性
//利用箭头函数可以解决这个函数的问题
//这个函数的作用域在实例对象里面的
this.Name1.addEventListener('click',function(){
//这里的this指向了this.Name1
for(let key in that.value){
//遍历设置修改的属性
that.Name.style[key]=that.value[key]
}
})
}
}
//属性是一个json
let sum = new Div('div.hh','.btn',{"backgroundColor":"black","height":"400px"})
sum.change()
</script>
</body>
构造函数 原型对象 实例对象之间的关系
通过构造函数创建对象
原型对象在构造函数内部 是构造函数的一个属性
实例对象和构造函数共用一个原型对象
原型对象的构造器指向构造函数
实例对象可以访问原型对象
js是通过原型继承的
_proto_和prototype
原型中的方法时可以在实例间相互访问的
原型链
在访问属性和方法的时候会首先在自己的实例对象上面找如果没有找继续往_proto_上找
如果没有找到继续找直到_proto_:Object都没有就会报错
Object是顶级对象 所有的类型都是Object构造出来的
所以只要在Object的原型链上封装一个方法那么所以的东西都可以使用这个方法包括简单类型
Es6的类其实是es5的语法糖 本质上在class里面定义的方法其实就是在构造函数的原型对象上面定义的
实例上并不存在方法 在构造器中定义的属性才是实例上都会创建的
重写Array.sort()
//在Array的原型上写方法所有被该构造函数构造的实例对象都会继承该方法
//复习一下this在被动用时指向被调用对象 所以这里this来代指实例对象
//当然也可以在函数内部放参数
Array.prototype.Mysort = function(){
for(let i =0 ;i<this.length-1;i++){
for(let j = 0;j<this.length-1-i;j++){
if(this[j]>this[j+1]){
let temp = this[j]
this[j] = this[j+1]
this[j+1] =temp
}
}
}
}
Array.prototype.UnMysort = function(){
for(let i =0 ;i<this.length-1;i++){
for(let j = 0;j<this.length-1-i;j++){
if(this[j]<this[j+1]){
let temp = this[j]
this[j] = this[j+1]
this[j+1] =temp
}
}
}
}
let arr = [1,5,4,3,2,7]
arr.Mysort()
console.log(arr)
arr.UnMysort()
console.log(arr)
立即执行函数
或者自调用函数
声明的同时直接调用
(function(形参){
})(实参)
可以将Window对象传递进立即执行函数内部
将函数内部的属性添加到Window上面由于Window是全局对象
就可以在外部访问内部的对象
(function(win){
let a = 123
win.a = a
})( global) //因为演示的是node.js环境 node.js没有Window对象
//全局对象为global
console.log(a) //123
call apply bind
call和apply都可以将一个函数的方法放在另一个函数内部或者另一个作用域里面使用
function test(a) {
this.a =a ;
console.log("xoxoxo")
this.sqyhello = function () {
console.log("xixixi")
}
}
function demo() {
test.call(this,13) //将test放在这里执行test的this绑定成了当前实例对象
console.log(this.a)//访问test上面的属性
this.sqyhello()//执行test上面的方法
}









网友评论