从零开始学_JavaScript_系列(20)——js系列<7>(函数原型的两种声明方式、函数的作用域)

简介:   (20)函数的原型 ①Object.create(obj) 根据原型obj创建一个对象; 例如: var obj = {    a: 1}var o1 = Object.create(obj);console.log(obj);console.log(o1); 输出为: Object {a: 1} Object {}   ②使用构造函数方法: 使用构造函

 

(20)函数的原型

①Object.create(obj)

根据原型obj创建一个对象;

例如:

var obj = {
    a: 1
}
var o1 = Object.create(obj);
console.log(obj);
console.log(o1);

输出为:

Object {a: 1}

Object {}

 

②使用构造函数方法:

使用构造函数,通过new来创建一个实例(之前有,这里略)

 

①和②之间的区别:

通过②的继承:

var obj = {
    a: 1
}
var o1 = Object.create(obj);
var o2 = Object.create(o1);
o1.b = 5;
o2.c = 2;
console.log(o1.b);
console.log(o2.b);

o1和o2都有属性b,并且值为5;

 

但是,通过继承来的,则不一样。

var obj = function () {
    a: 1
}
var o1 = function(){}
o1.prototype = new obj();
var o2 = function(){}
o2.prototype = new o1();
o1.b = 5;
o2.c = 2;
console.log(o1.b);
console.log(o2.b);

输出是5和undefined

 

通过查看console属性可以发现,Ojbect.create,其原型链是直接链接到创建时的原型对象的。

例如假设o2没有属性b,那么其值则为o1的属性b的值,假如o1.b的值被更改,那么o2.b的值也会被更改。

如代码:

var obj = {
    a: 1
}
var o1 = Object.create(obj);
var o2 = Object.create(o1);
o1.b = 3;
console.log(o2.b);
o1.b = 5;
console.log(o2.b);

其输出的值分别是3和5

 

 

④hasOwnProperty()

通过Object.create()方法声明的变量,其原型的属性,在自身调用 hasOwnProperty()会提示false

var obj = {
    a: 1
}
var o1 = Object.create(obj);
var o2 = Object.create(o1);
o1.b = 5;
console.log(o2.hasOwnProperty("b"));
o2.b = 2;
console.log(o2.hasOwnProperty("b"));

例如,第一个是true,第二个是false

但需要注意,这种方法无法通过

o2.prototype.b = 5;

来为之设置属性

 

而另一种方法和其的区别在于,可以通过o2.prototype.b = 5;来设置属性,以及继承。

 

 

 

(21)函数的作用域

①静态作用域:(JS使用的是这种)

var x = 1;
function a() {
    console.log(x);
}
function b() {
    var x = 2;
    a();
}
b();

输出结果是1,而不是2。

因为a()定义在window里,而不是在b()里,所以使用的是window中的x,而不是b中的x,如以下代码输出结果便为2:

var x = 1;
function b() {
    var x = 2;
    function a() {
        console.log(x);
    }
    a();
}
b();

 

 

②JS变量的作用域:全局作用域、函数作用域。没有块级作用域(即{}之间声明的变量的作用域);

 

③with方法的临时作用域:

var x = 1;
with ({x: 2}) {
    function a() {
        console.log(x);
    }
    (function () {
        console.log(" " + x);   //输出2
        a() //输出1
    })();
}
console.log(x); //输出1

 

之所以,是因为匿名函数可以理解为在函数内部创建并执行的(类似一个表达式),因此其内部变量的作用域是在with环境创建的临时作用域。(这个作用域,是x=2的作用域)

 

而a函数是声明的,因此其作用域是全局的(因为没有块级作用域,只有全局和函数内部的)。(函数被预解析时,知道其作用域是全局的)

 

由于with环境作用域是临时的,并且声明的是一个对象,因此不会对全局变量x进行修改。

 

 

 

目录
相关文章
|
22天前
|
存储 JavaScript 前端开发
解释 JavaScript 中的作用域和作用域链的概念。
【4月更文挑战第4天】JavaScript作用域定义了变量和函数的可见范围,静态决定于编码时。每个函数作为对象拥有`scope`属性,关联运行期上下文集合。执行上下文在函数执行时创建,定义执行环境,每次调用函数都会生成独特上下文。作用域链是按层级组织的作用域集合,自内向外查找变量。变量查找遵循从当前执行上下文到全局上下文的顺序,若找不到则抛出异常。
21 6
|
22天前
|
JavaScript
变量和函数提升(js的问题)
变量和函数提升(js的问题)
|
22天前
|
JavaScript
常见函数的4种类型(js的问题)
常见函数的4种类型(js的问题)
11 0
|
23天前
|
JavaScript
写一个函数将N组<>(包含开始和结束),进行组合,并输出组合结果 (js)
写一个函数将N组<>(包含开始和结束),进行组合,并输出组合结果 (js)
9 0
|
2天前
|
JavaScript 前端开发
js开发:请解释什么是ES6的Generator函数,以及它的用途。
ES6的Generator函数是暂停/恢复功能的特殊函数,利用yield返回多个值,适用于异步编程和流处理,解决了回调地狱问题。例如,一个简单的Generator函数可以这样表示: ```javascript function* generator() { yield 'Hello'; yield 'World'; } ``` 创建实例后,通过`.next()`逐次输出"Hello"和"World",展示其暂停和恢复的特性。
12 0
|
3天前
|
JavaScript 前端开发
js开发:请解释this关键字在JavaScript中的用法。
【4月更文挑战第23天】JavaScript的this关键字根据执行环境指向不同对象:全局中指向全局对象(如window),普通函数中默认指向全局对象,作为方法调用时指向调用对象;构造函数中指向新实例,箭头函数继承所在上下文的this。可通过call、apply、bind方法显式改变this指向。
7 1
|
9天前
|
缓存 JavaScript 前端开发
js的入口函数,入口函数的作用
js的入口函数,入口函数的作用
15 4
|
24天前
|
存储 前端开发 JavaScript
JavaScript如何封装一些常见的函数来提高工作效率
通过封装这些常见函数,你可以在项目中重复使用,提高代码的复用性和工作效率。这些函数包括获取元素、发起Ajax请求、处理本地存储、日期格式化、定时器等功能,可以在不同场景中减少重复的代码编写。
7 0
JavaScript如何封装一些常见的函数来提高工作效率
|
JSON JavaScript 数据格式
从零开始学_JavaScript_系列(22)——dojo(9)(表单、JsonRest的post方法,widget的使用思路)
(74)dojo的表单模块 插件:dojo/dom-form 参数:domForm 解释:        当我们需要像服务器提交很多内容时(比如很多个input输入框,还有一些单选按钮、多选按钮),我们必须将这些输入框的值变成一个对象(也许还要转为一个json字符串),在post的时候将其传递给服务器;          假如一个一个读过去,这也太傻了。所以这就是dom-for
1585 0
|
JavaScript 前端开发 Python
从零开始学_JavaScript_系列(21)——dojo(8)(手把手教你封装一个widget)
(73)封装一个widget 醒目:必须在web环境下使用,无论是python的web.py或者是通过http访问网站环境,都可以,但纯本地是不可行的。   首先,什么是widget? 简单来说,就是一个dom结点,比如像这样: <div>     这是一个dom结点 </div>   为什么需要widget呢? 很简单,比如,我们想在这样一个地方:
2041 0