js学习笔记02-类和对象,继承

创建类和对象

//1)构造函数定义类,不用new
function Dog(){
 this.name = "Luby";
 this.say = function(){
  console.log("wangwang!");
 }
}
let objDog = new Dog();  //创建对象的时候new
//2)工厂方式定义类
function Dog(){
  let dog = new Object;  //变量,然后new Object;
    dog.name = "Luby";
    dog.say = function(){
      console.log("wangwang");
    }
    return dog;
}
let dog = Dog();  //直接使用函数 
//以上两种方式的缺点:每一个新的对象都需要创建一个say();
//3)一般用原型+构造函数的方式定义类
function Dog(){
 this.name = "Luby";
}
Dog.prototype.say = function(){
  console.log("wangwang!");
 }
let objDog = new Dog();  //

构造函数

结构语法

//构造函数并不声明局部变量,而是使用 this 关键字来保存数据
//this 是指在构造函数前面使用 new 关键字创建的新对象
function SoftwareDeveloper() {
  this.useLanguage = 'JavaScript';
}
let developer = new SoftwareDeveloper();

查看对象的构造函数 (instanceof)

function SoftwareDeveloper() {
  this.useLanguage = 'JavaScript';
}
let developer = new SoftwareDeveloper();
developer instanceof SoftwareDeveloper; // instanceof返回值为true;

constructor 属性

每次创建一个对象时,都会有一个特殊的属性被暗中分配给它:constructor。访问一个对象的 constructor 属性会返回一个对创建该对象的构造函数的引用!

function Cat(){
 this.name = "fish";
}
let obj = new Cat();
console.log(obj.constructor); //  ƒ Cat(){this.name = "fish";)

如果某个对象是使用字面量表示法创建的,那么它的构造函数就是内置的 Object() 构造函数!

let obj = {
 name: "fish"
}
console.log(obj.constructor);//  ƒ Object() { [native code] } 
// 和java的class一样(每个class都有一个无参的什么都不做得构造函数)

this

当使用 new 运算符来调用构造函数时,this 变量会被设置为新创建的对象。当在对象上调用方法时,this 会被设置为该对象本身。当在浏览器环境中调用函数时,this 会被设置为 window,也被称为全局对象。

总结:

函数如何调用决定了函数内this的值(当前的函数属于谁或当前发生事件的对象)
构造函数中的this 是指在构造函数前面使用 new 关键字创建的新对象

this的应用: call(),apply(),bind()(回调函数)

call() 是一个直接调用到函数上的方法。我们传递给它一个单一的值,以设置为 this 的值,然后逐个传入该函数的任何参数,用逗号分隔。
apply()区别就是后面的多个参数为数组,事先并不知道函数所需要的参数个数就使用apply

const num = {
  sum: function (n1,n2) {
    return n1*n2;
  }
};
const title = {
  n1: 25,
  n2: 18.0
}
console.log(num.sum.call(title,title.n1,title.n2));//450  相当于把.call前面的方法声明到obj这个对象里面
console.log(num.sum.apply(title,[title.n1,title.n2]));

使用 bind() 来保存 this(回调函数中的this)

const dog = {
 age: 3,
 growOneYear: function(){
 this.age +=1;
}
}
function invokeTwice(cb) {
 cb();
 cb();
}
invokeTwice(dog.growOneYear);//这里的this为window
console.log(dog.age); //3
let change = dog.growOneYear.bind(dog);
invokeTwice(change); //由bind指定了this为dog
console.log(dog.age); //5

window 对象

页面的 URL (window.location;)
页面的垂直滚动位置 (window.scrollY)
滚动到新位置(window.scroll(0, window.scrollY + 200);,从当前位置向下滚动 200 个像素)
打开一个新的网页 (window.open("https://www.sugarbeans.com/");)

对象 Object

var goods = new Object();
Object.keys(goods);
Object.values(goods);

原型继承prototype

JavaScript 中的继承是指一个对象基于另一个对象
JavaScript 中的继承重点就是建立原型链
当使用 new 运算符将一个函数作为构造函数来调用时,该函数会创建并返回一个新的对象。这个对象会被秘密链接到其构造函数的 prototype,而它只是另一个对象。使用这个秘密链接,可以让一个对象访问原型的属性和方法,就像是它自己的一样。如果 JavaScript 没有在某个对象中找到一个特定属性,它将在原型链上继续查找。如有必要,它会一路查找到 Object()(顶级父对象)
proto(注意每一端有两个下划线)是构造函数所创建的所有对象(即实例)的一个属性,并直接指向该构造函数的 prototype 对象(警告:不要使用这个属性)
简单应用

function Cat(){
this.name = "coff";
}
let cat1 = new Cat();
let cat2 = new Cat();
Cat.prototype.say = function(){
  console.log("woool");
};
Cat.prototype.color = "red" //添加属性
Cat.prototype = { //指向了新的对象
 color: "red"
};
console.log(cat1.__proto__); //  {say: ƒ, color: "red", constructor: ƒ}

Object.create()

防止子对象修改父对象的属性 如:child.prototype.earBones = 5;
Object.create() 会接受一个对象作为参数,并返回一个新的对象,其 proto 属性会被设置为传递给它的参数。然后,你只需要将所返回的对象设置为子对象构造函数的原型即可

const mammal = {
   vertebrate: true,
   earBones: 3
};
const rabbit = Object.create(mammal); //Object.create()
console.log(rabbit);  // {}
console.log(rabbit.__proto__ === mammal); //true

构造函数之间的继承

function Animal(name){
  this.name = name;
}
Animal.prototype.walk = function(){
  console.log(`${this.name} walks!`);
} //定义了类Animal
function Cat(name){
  Animal.apply(this,[name]); //不使用new,使用父类的属性,如下:
     //let obj = new Animal(name);
 // this.name = obj.name;
}
Cat.prototype = Object.create(Animal.prototype); //类Cat继承Animal
let str = new Cat("miaomiao");
console.log(str.walk());

原型相关的函数

hasOwnProperty
hasOwnProperty() 可以帮助你找到某个特定属性的来源。在向其传入你要查找的属性名称的字符串后,该方法会返回一个布尔值,指示该属性是否属于该对象本身(即该属性不是被继承的)

function Phone() {
   this.operatingSystem = 'Android';
}
Phone.prototype.screenSize = 6;
const myPhone = new Phone();
const own = myPhone.hasOwnProperty('operatingSystem'); // true
const inherited = myPhone.hasOwnProperty('screenSize'); // false

isPrototypeOf()和Object.getPrototypeOf()
isPrototypeOf()可以检查某个对象是否存在于另一个对象的原型链中。
Object.getPrototypeOf()确定某个对象的原型是什么呢

const dog = {
 name: "hero",
 age: 2
}
function Cat(){
  this.say= function(){
  console.log("miaomiao") 
};
};
Cat.prototype = dog;  //
let str = new Cat();
//str.say();方法已经被覆盖
dog.isPrototypeOf(str); //true 注意调用顺序.
const myPrototype = Object.getPrototypeOf(str); //获取原型
console.log(myPrototype); //{name: "hero", age: 2}

猜你喜欢

转载自blog.51cto.com/5845595/2116150