对象创建
1.字面量方式
let str = 'name' ;
let obj = {
[str]:"张三" ,
age:"20" ,
hobby:function (){
console.log("喜欢篮球" )
}
}
2.构造函数
let obj = new Object();
obj.name = "张三" ;
obj.age = 20;
obj.hobby = function (){
console.log("喜欢篮球" )
}
console.log(obj);
3. Object.create() ;属性方法放在原型上;
let obj = Object.create({
name:"张三" ,
age:20,
hobby (){
console.log("喜欢篮球" );
}
})
4. 对象的调用
// 对象的调用;
console.log(obj.name);
console.log(obj['name' ]);
obj.hobby();
let str = "name" ;
console.log( obj.str); // undefined
console.log( obj[str]);
工厂模式
let zhangsan = {
name:"张三" ,
age:20,
hobby (){
console.log("喜欢篮球" );
}
}
let lisi = {
name:"李四" ,
age:21,
hobby (){
console.log("喜欢足球" );
}
}
// 工厂模式 :类
// 提高代码复用性
function Person(name,age,hobby){
let obj = {}; // 添加原料
obj.name = name;
obj.age = age;
obj.hobby = function (){
console.log(hobby);
}
// 加工原料
return obj; // 出厂;
}
let zhangsan = Person("张三" ,20,"喜欢篮球" );
let lisi = Person("李四" ,21,"喜欢足球" );
console.log(zhangsan);
console.log(lisi);
new
创建字符串
// let str = "" ;
// let str = new String();
new 执行函数时的特征
function test (){
console.log("test" );
}
test ();
new test (); // 需要传参时加括号
new test ;
自动创建一个空对象
把空对象和this绑定
如果没有返回,会隐式返回this
function Test (){
// let obj = {}; === this;
// return this;
}
new Test();
这里是工厂模式的简化:
原工厂模式
function Person(name,age,hobby){
let obj = {}; // 添加原料
obj.name = name;
obj.age = age;
obj.hobby = function (){
console.log(hobby);
}
// 加工原料
return obj; // 出厂;
}
简化后(构造函数)
// 工厂模式;
function Person(name,age,hobby){
// 手动创建空对象可以注释掉,new 运算符会帮我们做
// 把空对象和this绑定
// let obj = {}; // 添加原料 === this;
// 加工原料
this.name = name;
this.age = age;
this.hobby = function (){
console.log(hobby);
}
// 如果没有返回,会隐式返回this
// this 相当于 obj
// return obj; //出厂;
}
let zhangsan = new Person("张三" ,20,"篮球" );
console.log( zhangsan.name);
zhangsan.hobby();
构造函数
// 构造函数;1.首字母大写(约定俗成,与普通函数区分);2.this指向实例化对象;
function Person(name){
//注意:: name,age,hobby 都是跟实例化对象有关系的,属于zhangsan
this.name = name;
this.age =20;
this.hobby = function (){
console.log("喜欢篮球" );
}
}
// new : 实例化;
let zhangsan = new Person("张三" );
统计实例化的次数
function Person(name){
this.num = 0;
this.name = name;
this.age =20;
this.hobby = function (){
console.log("喜欢篮球" );
}
}
let zhangsan = new Person("张三" );
zhangsan.num ++;
console.log(zhangsan.num);
let lisi = new Person("李四" );
lisi.num ++;
console.log(lisi.num);
类的属性,静态属性和方法
function Person(name){
// this.num = 0;
this.name = name;
this.age =20;
this.hobby = function (){
console.log("喜欢篮球" );
}
}
// 静态成员;
// 静态属性和方法;(属于类本身的);
Person.num = 0;
Person.fn = function (){
console.log("fn" );
}
// new : 实例化;
let zhangsan = new Person("张三" );
Person.num++
let lisi = new Person("李四" );
Person.num++
console.log(Person.num);
构造函数的性能问题
hobby本身一个对象,比较的时候,不仅值要一样,在内存中的地址也要一样。两次实例化相对于开辟了不同的地址。100个人就会有100个地址,消耗内存。
function Person(name){
this.name = name;
this.age = 20;
this.hobby = function (){
console.log("喜欢篮球" );
}
}
let zhangsan = new Person("张三" );
let lisi = new Person("李四" );
console.log(zhangsan.hobby===lisi.hobby);
原型
每个构造函数实例化的过程中,都会有两部分构成:构造函数 + 公共空间——原型
构造函数每次实例化的过程中,在内存中会去开辟新的地址
prototype 在内存中都是公共的空间,节约内存。每次声明构造函数的时候,会自动声明一个原型,原型中的this也是指向实例化对象
function Person(name){
this.name = name;
this.age = 20;
// this.hobby = function (){
// console.log("喜欢篮球" );
// }
}
// 公共空间原型;
Person.prototype.hobby = function (){
console.log("喜欢篮球" );
}
let zhangsan = new Person("张三" );
let lisi = new Person("李四" );
console.log(zhangsan.hobby===lisi.hobby);
function Person(name){
this.name = name;
this.age = 20;
}
// 公共空间原型;
Person.prototype.hobby = function (){
console.log("喜欢篮球" );
}
let zhangsan = new Person("张三" );
// 得到zhangsan 对象,对象由两部分构成:自身的属性跟方法 + 自身的原型__proto__
console.log(zhangsan.__proto__ )
console.log(Person.prototype)
console.log(zhangsan.__proto__===Person.prototype);
// zhangsan.__proto__, Person.prototype 表现形式不同,其实是一个东西
let lisi = new Person("李四" );
constructor
function Person(name){
this.name = name;
this.age = 20;
}
// 功能空间原型;
Person.prototype.hobby = function (){
console.log("喜欢篮球" );
}
// 原型的固有属性;
console.log( Person.prototype.constructor===Person);
let zhangsan = new Person("张三" );
console.log(zhangsan.constructor===Person);
console.log(zhangsan);
勿在原型中覆盖属性
function Person(name){
this.name = name;
this.age = 20;
}
// 采用追加的方式可行
// Person.prototype.hobby = function (){
// console.log("喜欢篮球" );
// }
// 这种写法会覆盖掉constructor
Person.prototype = {
hobby:function (){
console.log("hobby" );
}
}
let zhangsan = new Person("张三" );
console.log(zhangsan.constructor===Person);
function Person(name){
this.name = name;
this.age = 20;
}
// 该写法需要自己加上constructor
// constructor 实例化对象是通过哪个构造函数来进行实例的
Person.prototype = {
constructor:Person,
hobby:function (){
console.log("hobby" );
}
}
let zhangsan = new Person("张三" );
console.log(zhangsan.constructor===Person);
判断类型
let str = new String("abd" );
// let str = "abc" ;
console.log(str.constructor===String);