JavaScript面向对象编程

本文深入探讨JavaScript的面向对象编程,讲解面向过程与面向对象的区别,详细阐述对象与类的概念,包括创建类、继承类的方法,以及构造函数与原型的相关知识,如原型链、成员查找机制和this指向。此外,还介绍了ES5新增的数组操作方法和对象属性管理功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面向对象编程思想

1. 面向过程与面向对象区别

面向对象面向过程
易维护、易复用、易扩展性能比面向对象高,适合跟硬件联系紧密
性能比面向过程低不易维护

2. 对象与类

在ES6中增加了类的概念,可以使用 class 关键字声明一个类,之后以这个类来实例化对象。类抽象了对象的公共部分,它泛指某一大类(class)对象特指某一个,通过类实例化一个具体的对象

2.1 创建类

  1. 语法规范:
  2. 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
  3. 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
  4. constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数
  5. 多个函数方法之间不需要添加逗号分隔
  6. 生成实例 new 不能省略
  7. 语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需要加function
	<script>
		//1.声明一个类
		class Father{
			//构造函数  实例化对象时自动会执行构造函数  可以用来传参
			constructor(x,y){
				this.name = x;
				this.age = y;
			}
			sing(){
				console.log("我是father");
			}
		}
		//2.使用自定义类实例化一个对象
		var father = new Father("name","age");
		//3.调用
		console.log(father.name);   //  输出"name"
		father.sing();				//	输出"我是father"	
	</script>

2.2 继承类

继承类使用关键字extends

	<script>
		//1.声明一个父类
		class Father{
			//构造函数  实例化对象时自动会执行构造函数  可以用来传参
			constructor(x,y){
				this.x = x;
				this.y = y;
			}
			sum(){
				console.log(this.x+this.y);
			}
		}
		//2.继承父类
		class Son extends Father{
			contructor(x,y){				//参数传递2:接受参数
			// 利用super 调用父类的构造函数 super 必须在子类this之前调用,放到this之后会报错
				super(x,y);					//参数传递3:调用父类构造函数 并传参
				this.x = x;
				this.y = y;
			}
			subtract(){
				console.log(this.x-this.y);	//调用 使用的是子类的x y
			}
		}
		//3.使用自定义类实例化一个对象
		var son = new Son(5,3);				//参数传递1:实例化传给son类的构造函数
		//4.调用
		son.sum();				//	输出"8"		传参给son的构造函数 再通过super传参给父类的构造函数
		son.subtract();			//	输出"2"	
	</script>

3. 构造函数与原型

3.1 创建对象的三种方式

 <script>
        // 1.字面量创建对象
        var obj1 = {};
        // 2.new关键字
        var obj2 = new Object();
        // 3.构造函数创建对象
        function Star(name,age){
            this.name = name;
            this.age = age;
        }
        var obj3 = new Star("洪吉潮",18);
    </script>

3.2 静态成员与实例成员

<script>
        // 1.字面量创建对象
        var obj1 = {};
        // 2.new关键字
        var obj2 = new Object();
        // 3.构造函数创建对象
        function Star(name,age){
            this.name = name;
            this.age = age;
        }
        var obj3 = new Star("洪吉潮",18);
        // 4.访问
        console.log(obj3.name);     //实例成员只能通过实例化对象访问
        Star.scale = 100;           //在构造函数本身添加成员,为静态成员
        console.log(Star.scale);    //静态成员只能通过构造函数对象来访问
    </script>

3.3 构造函数的问题

构造函数方法很好用,但是存在浪费内存的问题

在这里插入图片描述

3.4 构造函数原型对象prototype

    <script>
        //声明一个构造函数
        //每一个object都有一个__proto__对象原型 指向Star的prototype
        function Star(name,age){
            this.name = name;
            this.age = age;
        }
        //实例化对象
        var obj = new Star('hjc',18);
        //Star的prototype
        Star.prototype.sing = function(){
            console.log("我会唱歌");
        }
        console.log(obj);
        obj.sing();
    </script>

3.5 对象原型__proto__

  1. 构造函数都有一个prototype原型对象
  2. 实例化对象有一个__proto__对象原型
  3. __proto__对象原型指向构造函数的prototype
  4. 可以通过实例化对象访问构造函数Star的prototype的原型对象

在这里插入图片描述

3.6 constructor构造函数

  1. 每一个对象原型( _ proto _ )和原型对象(prototype)都有一个constructor属性
  2. constructor构造函数 指回函数的本身
		<script>
        // 1. 每一个对象原型( _ _proto_ _ )和原型对象(prototype)都有一个constructor属性
        // 2. constructor构造函数 指回函数的本身
        function Star(name,age){
            this.name = name;
            this.age = age;
        }
        //实例化对象
        var obj = new Star('hjc',18);
        console.log(Star.prototype.constructor);
        console.log(obj.__proto__.constructor);
        </script>

上述代码console输出结果

在这里插入图片描述

一般我们用这个constructor指回函数本身

	<script>
	    // 1. 每一个对象原型( _ _proto_ _ )和原型对象(prototype)都有一个constructor属性
        // 2. constructor构造函数 指回函数的本身
        function Star(name,age){
            this.name = name;
            this.age = age;
        }
        Star.prototype = {
            constructor:Star, // 利用constructor属性指回构造函数本身
            sing:function(){console.log('我会唱歌');},
            dance:function(){console.log('我会跳舞');}
        }
        //通过对象给prototype原型对象赋值,会把自带的constructor给去除
        //实例化对象
        var obj = new Star('hjc',18);

        console.log(Star.prototype.constructor);

        console.log(obj.__proto__.constructor);
	</script>

3.7 原型链

每一个实例对象又有一个 _ proto _ 属性,指向的构造函数的原型对象,构造函数的原型对象也是一个对象,也有 _ proto _ 属性,这样一层一层往上找就形成了原型链。

在这里插入图片描述

3.8 构造函数实例和原型对象的三角关系

1.Star有一个原型对象prototype属性
2.Star原型对象prototype.constructor能指向构造函数本身
3.实例化对象有一个 _ _ proto _ _ 属性 指向 Star原型对象prototype

在这里插入图片描述

3.9 原型链和成员的查找机制

1.当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性
2.如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)
3.如果它的原型没有找到该属性,就去这个原型的原型对象找该属性
4.直到原型对象最后返回一个null为止

3.10 原型对象中的this指向

构造函数中的this和原型对象的this,都指向我们new出来的实例对象

	<script>
		function Star(uname, age) {
	    this.uname = uname;
	    this.age = age;
		}
		var that;
		Star.prototype.sing = function() {
		    console.log('我会唱歌');
		    that = this;
		}
		var ldh = new Star('刘德华', 18);
		// 1. 在构造函数中,里面this指向的是对象实例 ldh
		console.log(that === ldh);//true
		// 2.原型对象函数里面的this 指向的是 实例对象 ldh
	</script>

3.11通过原型为数组拓展内置对象

通过原型拓展内置对象

<script>
        console.log(Array.prototype);     
        Array.prototype.sum = function(){
            var sum = 0;
            for(var i=0;i<this.length;i++){
                sum += this[i];
            }
            return sum;
        }
        
        var arr = new Array(5,10,15,20);
        
        console.log(arr.sum());
</script>

4. 继承

4.1 call()

  1. call()可以调用函数
  2. call()可以修改this的指向
    <script>
        function fn(x,y){
            console.log(this);
            console.log(x+y);
        }
        var o = {
            name:"andy"
        }
        fn(5,10);   //指向window的对象
        fn.call(o,5,15); //指向o的对象
    </script>

4.2 子构造函数继承父构造函数中的属性

    <script>
        function Star(name,age){
            this.name = name;
            this.age = age;
        }
        function Son(name,age,scale){
            //使用call,继承父构造函数的Star.name属性
            Star.call(this,name,age);
            this.scale = scale;
        }
        var son = new Son('hjc',18,100);
        console.log(son);
    </script>

4.3 借用原型对象继承方法

    <script>
        function Star(name,age){
            this.name = name;
            this.age = age;
        }
        Star.prototype.sing = function(){
            console.log('唱歌');
        }
        function Son(name,age,scale){
            //使用call,继承父构造函数的Star.name属性
            Star.call(this,name,age);
            this.scale = scale;
        }
        //实例化star对象赋值给prototype  此时constructor是指向的是star的本身
        Son.prototype = new Star();
        //让constructor指向调用者son的本身
        Son.prototype.constructor = Son;
        var son = new Son('hjc',18,100);
        console.log(son.__proto__.constructor);
        son.sing();
    </script>

5.0 ES5新增方法

5.1 forEach遍历数组

1.遍历数组,没有返回值

<script>
        var arr = [{id:1,name:'111'},{id:2,name:'222'}];
        arr.forEach(function(value,index,arr){
            //value 当前数据的值
            //index 当前数据的索引号
            //arr 当前数组
            //console.log(value);
            //console.log(index);
            //console.log(arr);

            //console.log(value.id + " " + value.name);
        })
    </script>

5.2filter过滤数组

1.遍历数组,会返回新的数组

	<script>
        var arr = [{id:1,name:'111'},{id:2,name:'222'},{id:3,name:'333'},{id:4,name:'444'},{id:5,name:'555'}];
        var newArr = arr.filter(function(value,index,arr){
            //value 当前数据的值
            //index 当前数据的索引号
            //arr 当前数组
            return value.id>3;
        });
        console.log(newArr);
    </script>

5.3 some查找数组

<script>
        var arr = [{id:1,name:'111'},{id:2,name:'222'},{id:3,name:'222'},{id:4,name:'444'},{id:5,name:'555'}];
        var res = arr.some(function(value){
            if(value.name === "222"){
                return true;  //当查找到222时,返回一个true,会终止本次迭代(遍历)
            }
            console.log(value);
        });
        console.log(res);
    </script>

5.4 trim()方法 去除空白字符串

	<script>
		str.trim();
	</script>

5.5 Object.keys() 获取对象自有属性

	<script>
		var obj = {
			id:1,
			name:'hjc',
			scale:100,
			age:18
		}
		Object.keys(obj);	//返回所有属性名的数组
		
	</script>

5.6 Object.defineProperty() 添加或修改对象中的属性

	<script>
	/*
		Object.defineProperty(对象,修改或新增的属性名,{
		value:修改或新增的属性的值,
		writable:true/false,//如果值为false 不允许修改这个属性值
		enumerable: false,//enumerable 如果值为false 则不允许遍历
        configurable: false  //configurable 如果为false 则不允许删除这个属性 属性是否可以被删除或是否可以再次修改特性
    */
})	
	</script>
	<script>
        var personObj = {
            id:001,
            name:'张三',
            age:18
        }
        Object.defineProperty(personObj,'sex',{
            value:'男',
            enumerator:true,
            writable:true. //设置为false,第十行的修改属性失效
        })
        personObj.sex = '女'; //第十行
        console.log(personObj.sex);
    </script>

本节新get知识点

	<script>
		
		1.insertAdjacentHTML()insertAdjacentText()
		ele.insertAdjacentHTML(swhere,stext)
		/*参数:
		swhere: 指定插入html标签语句的地方,
		stext:要插入的内容
		有四种值可用:
		1.beforeBegin: 插入到标签开始前
		2.afterBegin:插入到标签开始标记之后
		3.beforeEnd:插入到标签结束标记前
		4.afterEnd:插入到标签结束标记后
		*/
		
		2.双击事件去除选中文本效果
		window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
	</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值