JS高级-1:对象、构造函数、函数(方法)
2021-04-18 22:27
标签:最新 面向 执行函数 实现继承 动作 部分 nav ring 介绍 局限性:Animal(父类构造函数)的代码必须完全适用于Person(子类构造函数) //-->1、首先查看本身有没有length属性 JS高级-1:对象、构造函数、函数(方法) 标签:最新 面向 执行函数 实现继承 动作 部分 nav ring 介绍 原文地址:https://www.cnblogs.com/qfshini/p/12274369.htmlJS高级第一天
JS基本介绍
数据类型
对象的基本使用
创建一个对象
var student={
name:"李白" , //student有一个name属性,值为"李白"
grade:"初一" ,
//a、student有一个say属性,值为一个函数
//b、student有一个say方法
say:function(){
console.log("你好");
},
run:function(speed){
console.log("正在以"+speed+"米/秒的速度奔跑");
}
}
对象是键值对的集合:对象是由属性和方法构成的 (ps:也有说法为:对象里面皆属性,认为方法也是一个属性)
对象属性操作
获取属性:
第一种方式:.语法
第二种方式:[]语法
号外:2种方式的差异:
var obj={};
obj.this=5; //语法错误
obj.0=10; //语法错误
obj["this"]=10
obj[3]=50 = obj["3"]=50
设置属性
student["gender"]="男"
等价于: student.gender="男"
如果student对象中有gender属性,就修改gender属性的值为"男"
student.isFemale=true
student["children"]=[1,2,5]
student.toShanghai=function(){
console.log("正在去往上海的路上")
}
删除属性
通过构造函数创建对象
构造函数创建对象的例子:
var isMale=/123/;
==> var isMale=new RegExp("123")
自定义一个构造函数来创建对象
function Person(name,age){
this.name=name;
this.age=age;
}
var p1=new Person("赵云",18)
p1就是根据【Person构造函数】创建出来的对象
构造函数的概念
function CreateFunc(){ }
关于new Object()
构造函数的执行过程
var p1=new Person();
_p1
this
,将this指向该实例(_p1)
function fn(){
}
var f1=new fn(); //f1就是fn的实例
function fn2(){
return "abc";
}
var f2=new fn2(); //f2是fn2构造函数的实例
function fn3(){
return [1,3,5];
//数组是一个对象类型的值,
//所以数组是一个复杂数据类型的值
//-->本次构造函数的真正返回值就是该数组
//-->不再是fn3构造函数的实例
}
var f3=new fn3(); //f3还是fn3的实例吗?错
//f3值为[1,3,5]
继承
JS中继承的概念:
并不是所谓的xxx extends yyy
为什么要使用继承?
function Person(){
this.say=function(){
console.log("你好")
}
}
var p1=new Person();
var p2=new Person();
console.log(p1.say === p2.say); //false
继承的第一种方式:原型链继承1
Person.prototype.say=function(){
console.log("你好")
}
继承的第二种方式:原型链继承2
Person.prototype = {
//切记不能忘记
constructor:Person,
say:function(){
console.log("你好");
},
run:function(){
console.log("正在进行百米冲刺");
}
}
继承的第三种方式:拷贝继承(混入继承:mixin)
var o1={ age:2 };
var o2 = o1;
o2.age=18;
//1、修改了o2对象的age属性
//2、由于o2对象跟o1对象是同一个对象
//3、所以此时o1对象的age属性也被修改了
var o3={gender:"男",grade:"初三",group:"第五组",name:"张三"};
var o4={gender:"男",grade:"初三",group:"第五组",name:"李四"};
//上述代码中,如果使用拷贝继承对代码进行优化会非常和谐
//实现拷贝继承:
//1、已经拥有了o3对象
//2、创建一个o3对象的拷贝(克隆):for...in循环
//3、修改克隆对象,把该对象的name属性改为"李四"
var source={name:"李白",age:15}
var target={};
target.name=source.name
target.age=source.age;
var students=[
{name:"",age:""},
{name:"",age:""}
]
function extend(target,source){
for(key in source){
target[key]=source[key];
}
return target;
}
extend(target,source)
var source={name:"李白",age:15}
//让target是一个新对象,同时拥有了name、age属性
var target={ ...source }
var target2={ ...source,age:18 }
继承的第四种方式:原型式继承:(道格拉斯在蝴蝶书中提出来的)
js var parent={ age:18,gender:"男"}; var student=Object.create(parent); //student.__proto__===parent
var o1={ say:function(){} }
var o2=Object.create(o1);
继承的第五种方式:借用构造函数实现继承
function Animal(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
function Person(name,age,gender,say){
this.name=name;
this.age=age;
this.gender=gender;
this.say=function(){
}
}
function Animal(name,age){
this.name=name;
this.age=age;
}
function Person(name,age,address){
Animal.call(this,name);
//this.name=name;
//this.age=age;
this.address=address;
}
原型链(家族族谱)
-意义:可以实现让该对象访问到父对象中相关属性
function Animal(){}
var cat=new Animal();
//cat.__proto__:Animal.prototype
//cat.__proto__.__proto__:根对象
闭包
变量作用域
var age=18; //age是在全局作用域中声明的变量:全局变量
function f1(){
console.log(name); //可以访问到name变量
var name="周董" //name是f1函数内部声明的变量,所以name变量的作用域就是在f1函数内部
console.log(name); //可以访问到name变量
console.log(age); //age是全局作用域中声明的,所以age也可以访问
}
console.log(age); //也可以访问
//多级作用域
//-->1级作用域
var gender="男";
function fn(){
//问题:
//gender:可以访问
//age: 可以访问
//height:不能访问
//-->2级作用域
return function(){
//问题:
//gender: 通过一级一级作用域的查找,发现gender是全局作用域中声明的变量
//age:
//height:
console.log(gender);
//-->3级作用域
var height=180;
}
var age=5;
}
作用域链
var name="张三";
function f1(){
var name="abc";
console.log(name);
}
f1();
var name="张三";
function f1(){
console.log(name);
var name="abc";
}
f1();
var name="张三";
function f1(){
console.log(name);
var name="abc";
}
f1();
var name="张三";
function f1(){
return function(){
console.log(name);
}
var name="abc";
}
var fn=f1();
fn();
var name="张三";
function f1(){
return {
say:function(){
console.log(name);
var name="abc";
}
}
}
var fn=f1();
闭包的问题
function fn(){
var a=5;
return function(){
a++;
console.log(a);
}
}
var f1=fn();
f1();
f1();
f1();
闭包问题的产生原因
闭包的应用场景
函数的4种调用方式
ES6之前
,函数内部的this是由该函数的调用方式决定的
var age=18;
var p={
age:15
say:function(){
console.log(this.age);//window.age:18
}
}
var s1=p.say
s1(); //函数调用
var age=18;
var p={
age:15
say:function(){
console.log(this.age);//this:p
//this.age->p.age:15
}
}
p.say()//方法调用
var age=18;
var p={
age:15
say:function(){
//this:say构造函数的实例,实例中并没有age属性,值为:undefined
console.log(this.age);
}
}
new p.say()//构造函数调用
//相当于:
var s1=p.say;
new s1();
var length=21;
function f1(){
console.log(this.length);
}
f1.call([1,3,5]) //3
f1.apply(this) //window.length:21
f1.call(5) //undefined
原型
对象的属性查找规则
//-->2、如果本身没有该属性,那么去它的原型对象中查找
//-->3、如果原型对象中没有,那么就去原型对象的原型对象中查找,最终一直找到根对象(Object.prototype)
//-->4、最终都没有找到的话,我们认为该对象并没有该属性,如果获取该属性的值:undefined补充,判断数据类型
Object.prototype.toString.call()
指向window
$.ajax({
success:function(){
console.log(this); //window
}
})
[1,3,5].map(function(){
console.log(this); //window
})
$("div")
`${$}`
`${$('div')}`
global和window的区别
上一篇:第七篇:Ajax功能模块
下一篇:Kubernetes学习(四)